Widgets
Widgets are responsible to render field for the form/read data from the POST data.
Widget has to implement following interface:
type WidgetData map[string]interface{}type IWidget interface { IDForLabel(model interface{}, F *Field) string GetWidgetType() WidgetType GetAttrs() map[string]string GetTemplateName() string SetTemplateName(templateName string) RenderUsingRenderer(renderer ITemplateRenderer) // GetValue(v interface{}, model interface{}) interface{} Render(formRenderContext *FormRenderContext, currentField *Field) string SetValue(v interface{}) SetName(name string) GetDataForRendering(formRenderContext *FormRenderContext, currentField *Field) WidgetData SetAttr(attrName string, value string) SetBaseFuncMap(baseFuncMap template.FuncMap) InitializeAttrs() SetFieldDisplayName(displayName string) SetReadonly(readonly bool) GetValue() interface{} ProceedForm(form *multipart.Form, afo IAdminFilterObjects, renderContext *FormRenderContext) error SetRequired() SetShowOnlyHTMLInput() SetOutputValue(v interface{}) GetOutputValue() interface{} SetErrors(validationErrors ValidationError) RenderForAdmin() SetHelpText(helpText string) IsValueChanged() bool SetPopulate(func(renderContext *FormRenderContext, currentField *Field) interface{}) SetPrefix(prefix string) GetHTMLInputName() string GetPopulate() func(renderContext *FormRenderContext, currentField *Field) interface{} IsReadOnly() bool IsValueConfigured() bool SetValueConfigured() GetRenderer() ITemplateRenderer GetFieldDisplayName() string GetName() string}
In most cases it's ok to extend Widget structure for your own widget, like here:
type TextWidget struct { Widget}
func (tw *TextWidget) GetWidgetType() WidgetType { return TextInputWidgetType}
func (tw *TextWidget) GetTemplateName() string { if tw.TemplateName == "" { path := "widgets/text" if tw.IsForAdmin { path = "admin/" + path } return CurrentConfig.GetPathToTemplate(path) } return CurrentConfig.GetPathToTemplate(tw.TemplateName)}
func (tw *TextWidget) Render(formRenderContext *FormRenderContext, currentField *Field) string { // spew.Dump("2", tw.FieldDisplayName) data := tw.Widget.GetDataForRendering(formRenderContext, currentField) data["Type"] = tw.GetWidgetType() data["ShowOnlyHtmlInput"] = tw.ShowOnlyHTMLInput return RenderWidget(tw.Renderer, tw.GetTemplateName(), data, tw.BaseFuncMap) // tw.Value, tw.Widget.GetAttrs()}
Currently we support following widgets:
// widget where widget could be determined dynamically.type DynamicWidget struct { Widget GetRealWidget func(formRenderContext *FormRenderContext, currentField *Field) IWidget GetRealWidgetForFormProceeding func(form *multipart.Form, afo IAdminFilterObjects) IWidget}// text widgettype TextWidget struct { Widget}// foreign key link widgettype FkLinkWidget struct { Widget}// widget to display field as numbertype NumberWidget struct { Widget NumberType UadminFieldType}// widget to display field as emailtype EmailWidget struct { Widget}// widget to display field as urltype URLWidget struct {
}// widget to display field as passwordtype PasswordWidget struct { Widget}// widget to display field as hidden inputtype HiddenWidget struct { Widget}// widget to display field as date, currently we don't support date pickertype DateWidget struct { Widget DateValue string}// widget to display field as datetime, currently we don't support date pickertype DateTimeWidget struct { Widget DateTimeValue string}// widget to display field as time, currently we don't support time pickertype TimeWidget struct { Widget TimeValue string}// widget to display field as textareatype TextareaWidget struct { Widget}// widget to display field as checkboxtype CheckboxWidget struct { Widget}// widget to display field as selecttype SelectWidget struct { Widget OptGroups map[string][]*SelectOptGroup DontValidateForExistence bool}// widget to display field as foreign key, it fetches automaitcally all options to be choosed fromtype ForeignKeyWidget struct { Widget OptGroups map[string][]*SelectOptGroup DontValidateForExistence bool AddNewLink string GetQuerySet func(formRenderContext *FormRenderContext) IPersistenceStorage GenerateModelInterface func() (interface{}, interface{})}// widget to display field as content type, it fetches automaitcally all content types to be choosed fromtype ContentTypeSelectorWidget struct { Widget OptGroups map[string][]*SelectOptGroup LoadFieldsOfAllModels bool}// not tested in UI. To be described later.type NullBooleanWidget struct { Widget OptGroups map[string][]*SelectOptGroup}// not tested in UI. To be described later.type SelectMultipleWidget struct { Widget OptGroups map[string][]*SelectOptGroup}// not tested in UI. To be described later.type RadioSelectWidget struct { Widget OptGroups map[string][]*RadioOptGroup ID string WrapLabel bool}// not tested in UI. To be described later.type CheckboxSelectMultipleWidget struct { Widget OptGroups map[string][]*RadioOptGroup ID string WrapLabel bool}// it allows you to store uploaded file, by default it uploads to the FS. To the directory for uploaded files,// but it can be easily changed to store it to S3 or any different place.// Please check out documentation for storages to understand how to do that.type FileWidget struct { Widget Storage IStorageInterface UploadPath string Multiple bool}// not tested in UI. To be described later.type ClearableFileWidget struct { Widget InitialText string CurrentValue *URLValue Required bool ID string ClearCheckboxLabel string InputText string Storage IStorageInterface UploadPath string Multiple bool}// not tested in UI. To be described later.type MultipleInputHiddenWidget struct { Widget}// implements it like: two selects(left and right side) and it allows you to move between two selectstype ChooseFromSelectWidget struct { Widget PopulateLeftSide func() []*SelectOptGroup PopulateRightSide func() []*SelectOptGroup LeftSelectTitle string LeftSelectHelp string LeftHelpChooseAll string LeftSearchSelectHelp string LeftChooseAllText string RightSelectTitle string RightSelectHelp string RightHelpChooseAll string RightSearchSelectHelp string RightChooseAllText string AddNewLink string AddNewTitle string}// splits date and time into two separated fields, not tested in UI. To be described later.type SplitDateTimeWidget struct { Widget DateAttrs map[string]string TimeAttrs map[string]string DateFormat string TimeFormat string DateLabel string TimeLabel string DateValue string TimeValue string}// not tested in UI. To be described later.type SplitHiddenDateTimeWidget struct { Widget DateAttrs map[string]string TimeAttrs map[string]string DateFormat string TimeFormat string DateValue string TimeValue string}// implements it like three separated selects: for year, month, day// not tested in UI. To be described later.type SelectDateWidget struct { Widget Years []int Months []*SelectOptGroup EmptyLabel []*SelectOptGroup EmptyLabelString string YearValue string MonthValue string DayValue string}