-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dynamic forms options? #29
Comments
Ok so my current solution for this isn't pretty but it works. Maybe this can be improved, please let me know if you have suggestions:
Here is most of the relevant code: type value =
| String(string)
| NoValue;
type field =
| Title
| Option(int)
| AddOption
| DelOption(int);
let get = (field, state) =>
switch (field) {
| Title => String(state.title)
| Option(index) =>
state.options
|. Belt.Array.get(index)
|. Belt.Option.getWithDefault("")
|. String
| DelOption(_index) => NoValue
| AddOption => NoValue
};
let baseValidators =
Formality.(
Validators.empty
|> Validators.add(
Title,
{
strategy: Strategy.OnFirstChange,
dependents: None,
validate: isRequired,
},
)
);
let validators =
Formality.(
Belt.Array.range(0, 100)
|. Belt.Array.reduce(baseValidators, (result, i) =>
result
|> Validators.add(
Option(i),
{
strategy: Strategy.OnFirstChange,
dependents: None,
validate: isShorterThan(50),
},
)
)
);
let update = ((field, value), state) =>
switch (field, value) {
| (Option(index), String(value)) =>
state.options |. Belt.Array.set(index, value) |> ignore;
state;
| (AddOption, _value) =>
state.options |> Js.Array.push("") |> ignore;
state;
| (DelOption(index), _novalue) => {
...state,
options: state.options |> Js.Array.filteri((_o, i) => i != index),
}
| _ => failwith("Config.update function received bad input")
};
/* Later on in the render function... */
<ol>
(
form.state.options
|> Array.mapi((i, o) =>
<li key=(i |> string_of_int)>
<input
value=(
form.state.options
|. Belt.Array.get(i)
|. Belt.Option.getWithDefault("")
)
onChange=(
event =>
event
|> Formality.Dom.toValueOnChange
|. Form.String
|> form.change(Form.Option(i))
)
/>
(
i >= 2 ?
<a
onClick=(
_event =>
form.change(DelOption(i), NoValue)
)>
("[-]" |> ReasonReact.string)
</a> :
ReasonReact.string("")
)
(
switch (Form.Option(i) |> form.results) {
| Some(Invalid(message)) =>
<div className="failure">
(message |> ReasonReact.string)
</div>
| Some(Valid) =>
<div className="success">
({j|✓|j} |> ReasonReact.string)
</div>
| None => ReasonReact.null
}
)
</li>
)
|> ReasonReact.array
)
</ol>
<a onClick=(_event => form.change(AddOption, NoValue))>
("Add option" |> ReasonReact.string)
</a> |
Hey, thanks for kind words! TBH I haven't tried to implement it yet and I'd started poking around by changing type value =
| String(string)
| ArrayOfStrings(array(string)); If your solution works I'd leave it like this, for now. ATM I'm focused on shipping |
Let's continue in #43 |
First of all thank you @alexfedoseev for creating this, it's the best form library I've seen for ReasonML so far.
I'm working on a form that has a field that is an array of strings, where options can be dynamically added and removed. There should be between 2-30 items in the array, and each string should be between 1-140 characters.
This seems like it should be possible, but I'm wondering if you could provide some guidance/examples of how to accomplish this with Formality? Thanks again.
The text was updated successfully, but these errors were encountered: