Elm 具有可组合形式的动态形式
我正在尝试使用实现Elm 0.19中的动态表单 我收到一个带有字段、字段描述等的json,所以我事先不知道它将包含多少字段 因此,定义表单的传统方式是:Elm 具有可组合形式的动态形式,elm,Elm,我正在尝试使用实现Elm 0.19中的动态表单 我收到一个带有字段、字段描述等的json,所以我事先不知道它将包含多少字段 因此,定义表单的传统方式是: Form.succeed OutputValues |> Form.append field1 |> Form.append field2 不起作用,因为我事先不知道OutputValues结构 我看到有一个函数Form.list,它看起来是一个很有前途的路径,尽管它似乎期望所有字段都相等,但我的情况并非如
Form.succeed OutputValues
|> Form.append field1
|> Form.append field2
不起作用,因为我事先不知道OutputValues
结构
我看到有一个函数Form.list
,它看起来是一个很有前途的路径,尽管它似乎期望所有字段都相等,但我的情况并非如此,例如,我可能有一个文本字段和一个选择字段
这个图书馆有没有直接的方法?
谢谢。表单库并不明确支持您尝试执行的操作,但我们可以让它正常工作 太长,读不下去了 下面是我的示例,说明如何获取JSON并创建表单: 怎么去那里
Form.list
无疑是一条有前途的道路。您也完全正确,Form.list
要求所有字段的类型都相同。让我们从这里开始吧!我们可以创建一个数据结构,通过创建自定义类型来保存它们。在我的示例中,我将其称为DynamicFormFieldValue
。我们将为每种字段制作一个变体。我为文本、整数和选择列表创建了一个。每一个都需要保存字段的值和所有附加值(如标题和默认值),以使其很好地显示出来。这就是我们将JSON解码成的内容,表单值是什么,表单输出是什么。结果类型如下所示:
type alias TextFieldRequirements =
{ name : String
, default : Maybe String
}
type alias IntFieldRequirements =
{ name : String
, default : Maybe Int
}
type alias SelectFieldRequirements =
{ name : String
, default : Maybe String
, options : List ( String, String )
}
type DynamicFormFieldValue
= TextField String TextFieldRequirements
| IntField Int IntFieldRequirements
| SelectField String SelectFieldRequirements
dynamicFormField : Int -> Form DynamicFormFieldValue DynamicFormFieldValue
dynamicFormField fieldPosition =
Form.meta
(\field ->
case field of
TextField textValue ({ name } as requirements) ->
Form.textField
{ parser = \_ -> Ok field
, value = \_ -> textValue
, update = \value oldValue -> TextField value requirements
, error = always Nothing
, attributes =
{ label = name
, placeholder = ""
}
}
IntField intValue ({ name } as requirements) ->
Form.numberField
{ parser = \_ -> Ok field
, value = \_ -> String.fromInt intValue
, update = \value oldValue -> IntField (Maybe.withDefault intValue (String.toInt value)) requirements
, error = always Nothing
, attributes =
{ label = name
, placeholder = ""
, step = Nothing
, min = Nothing
, max = Nothing
}
}
SelectField selectValue ({ name, options } as requirements) ->
Form.selectField
{ parser = \_ -> Ok field
, value = \_ -> selectValue
, update = \value oldValue -> SelectField value requirements
, error = always Nothing
, attributes =
{ label = name
, placeholder = ""
, options = options
}
}
)
要显示表单,您只需要一个函数,该函数可以接受表单值并显示适当的表单小部件。表单库提供了form.meta
来根据值更改表单。因此,我们将在自定义类型上进行模式匹配,并返回Form.textField
,Form.numberField
,或Form.selectField
。大概是这样的:
type alias TextFieldRequirements =
{ name : String
, default : Maybe String
}
type alias IntFieldRequirements =
{ name : String
, default : Maybe Int
}
type alias SelectFieldRequirements =
{ name : String
, default : Maybe String
, options : List ( String, String )
}
type DynamicFormFieldValue
= TextField String TextFieldRequirements
| IntField Int IntFieldRequirements
| SelectField String SelectFieldRequirements
dynamicFormField : Int -> Form DynamicFormFieldValue DynamicFormFieldValue
dynamicFormField fieldPosition =
Form.meta
(\field ->
case field of
TextField textValue ({ name } as requirements) ->
Form.textField
{ parser = \_ -> Ok field
, value = \_ -> textValue
, update = \value oldValue -> TextField value requirements
, error = always Nothing
, attributes =
{ label = name
, placeholder = ""
}
}
IntField intValue ({ name } as requirements) ->
Form.numberField
{ parser = \_ -> Ok field
, value = \_ -> String.fromInt intValue
, update = \value oldValue -> IntField (Maybe.withDefault intValue (String.toInt value)) requirements
, error = always Nothing
, attributes =
{ label = name
, placeholder = ""
, step = Nothing
, min = Nothing
, max = Nothing
}
}
SelectField selectValue ({ name, options } as requirements) ->
Form.selectField
{ parser = \_ -> Ok field
, value = \_ -> selectValue
, update = \value oldValue -> SelectField value requirements
, error = always Nothing
, attributes =
{ label = name
, placeholder = ""
, options = options
}
}
)
在库中连接此显示功能有点笨拙<代码>表单.列表的设计没有考虑用例。我们希望列表保持相同的长度,只需迭代即可。为了实现这一点,我们将删除“添加”和“删除”按钮,并强制提供一个虚拟的默认值(永远不会使用)
希望ellie示例能够演示其余内容,您可以根据自己的需要进行调整 此外,如果某些字段是必填字段或非必填字段,也可以按如下所示进行处理: