Exemplo n.º 1
0
func unWindStructure(m interface{}, baseName string) ([]interface{}, string) {
	t := reflect.TypeOf(m)
	v := reflect.ValueOf(m)
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
		v = v.Elem()
	}
	fieldList := make([]interface{}, 0)
	fieldSort := ""
	fieldSetList := make(map[string]*FieldSetType, 0)
	fieldSetSort := make(map[string]string, 0)
	for i := 0; i < t.NumField(); i++ {
		options := make(map[string]struct{})
		tag, tagf := formcommon.Tag(t, t.Field(i), "form_options")
		if tag != "" {
			var optionsArr []string = make([]string, 0)
			if tagf != nil {
				cached := tagf.GetParsed("form_options", func() interface{} {
					return strings.Split(formcommon.TagVal(t, i, "form_options"), ";")
				})
				optionsArr = cached.([]string)
			}
			for _, opt := range optionsArr {
				if opt != "" {
					options[opt] = struct{}{}
				}
			}
		}
		if _, ok := options["-"]; !ok {
			widget := formcommon.TagVal(t, i, "form_widget")
			var f fields.FieldInterface
			var fName string
			if baseName == "" {
				fName = t.Field(i).Name
			} else {
				fName = strings.Join([]string{baseName, t.Field(i).Name}, ".")
			}
			//fmt.Println(fName, t.Field(i).Type.String(), t.Field(i).Type.Kind())
			switch widget {
			case "color", "email", "file", "image", "month", "search", "tel", "url", "week":
				f = fields.TextFieldFromInstance(v, t, i, fName, widget)
			case "text":
				f = fields.TextFieldFromInstance(v, t, i, fName)
			case "hidden":
				f = fields.HiddenFieldFromInstance(v, t, i, fName)
			case "textarea":
				f = fields.TextAreaFieldFromInstance(v, t, i, fName)
			case "password":
				f = fields.PasswordFieldFromInstance(v, t, i, fName)
			case "select":
				f = fields.SelectFieldFromInstance(v, t, i, fName, options)
			case "date":
				f = fields.DateFieldFromInstance(v, t, i, fName)
			case "datetime":
				f = fields.DatetimeFieldFromInstance(v, t, i, fName)
			case "time":
				f = fields.TimeFieldFromInstance(v, t, i, fName)
			case "number":
				f = fields.NumberFieldFromInstance(v, t, i, fName)
			case "range":
				f = fields.RangeFieldFromInstance(v, t, i, fName)
			case "radio":
				f = fields.RadioFieldFromInstance(v, t, i, fName)
			case "checkbox":
				f = fields.CheckboxFieldFromInstance(v, t, i, fName)
			case "static":
				f = fields.StaticFieldFromInstance(v, t, i, fName)
			default:
				switch t.Field(i).Type.String() {
				case "string":
					f = fields.TextFieldFromInstance(v, t, i, fName)
				case "bool":
					f = fields.CheckboxFromInstance(v, t, i, fName, options)
				case "time.Time":
					f = fields.DatetimeFieldFromInstance(v, t, i, fName)
				case "int", "int64":
					f = fields.NumberFieldFromInstance(v, t, i, fName)
				case "float", "float64":
					f = fields.NumberFieldFromInstance(v, t, i, fName)
				case "struct":
					fl, fs := unWindStructure(v.Field(i).Interface(), fName)
					if fs != "" {
						if fieldSort == "" {
							fieldSort = fs
						} else {
							fieldSort += "," + fs
						}
					}
					fieldList = append(fieldList, fl...)
					f = nil
				default:
					if t.Field(i).Type.Kind() == reflect.Struct ||
						(t.Field(i).Type.Kind() == reflect.Ptr && t.Field(i).Type.Elem().Kind() == reflect.Struct) {
						fl, fs := unWindStructure(v.Field(i).Interface(), fName)
						if fs != "" {
							if fieldSort == "" {
								fieldSort = fs
							} else {
								fieldSort += "," + fs
							}
						}
						fieldList = append(fieldList, fl...)
						f = nil
					} else {
						f = fields.TextFieldFromInstance(v, t, i, fName)
					}
				}
			}
			if f != nil {
				label := formcommon.TagVal(t, i, "form_label")
				if label == "" {
					label = strings.Title(t.Field(i).Name)
				}
				label = formcommon.LabelFn(label)
				f.SetLabel(label)

				params := formcommon.TagVal(t, i, "form_params")
				if params != "" {
					if paramsMap, err := url.ParseQuery(params); err == nil {
						for k, v := range paramsMap {
							if k == "placeholder" || k == "title" {
								v[0] = formcommon.LabelFn(v[0])
							}
							f.SetParam(k, v[0])
						}
					} else {
						fmt.Println(err)
					}
				}
				valid := formcommon.TagVal(t, i, "valid")
				if valid != "" {
					ValidTagFn(valid, f)
				}
				fieldset := formcommon.TagVal(t, i, "form_fieldset")
				fieldsort := formcommon.TagVal(t, i, "form_sort")
				if fieldset != "" {
					fieldset = formcommon.LabelFn(fieldset)
					f.SetData("container", "fieldset")
					if _, ok := fieldSetList[fieldset]; !ok {
						fieldSetList[fieldset] = FieldSet(fieldset, f)
					} else {
						fieldSetList[fieldset].Elements(f)
					}
					if fieldsort != "" {
						if _, ok := fieldSetSort[fieldset]; !ok {
							fieldSetSort[fieldset] = fName + ":" + fieldsort
						} else {
							fieldSetSort[fieldset] += "," + fName + ":" + fieldsort
						}
					}
				} else {
					fieldList = append(fieldList, f)
					if fieldsort != "" {
						if fieldSort == "" {
							fieldSort = fName + ":" + fieldsort
						} else {
							fieldSort += "," + fName + ":" + fieldsort
						}
					}
				}
			}
		}
	}
	for _, v := range fieldSetList {
		if s, ok := fieldSetSort[v.Name()]; ok {
			v.Sort(s)
		}
		fieldList = append(fieldList, v)
	}
	return fieldList, fieldSort
}