feat: prevent short-circuit evaluation for validation
This commit is contained in:
1 parent
f08fee1246
commit
e0b54b96f9
3 files changed
+37
-20
No files matched your search
+21
-14
@@ -11,27 +11,27 @@ use std::collections::HashMap;
|
|||||||
pub enum InputType {
|
pub enum InputType {
|
||||||
/// Represents a text input. Requires a `String` key, `String` label, and `String` placeholder.
|
/// Represents a text input. Requires a `String` key, `String` label, and `String` placeholder.
|
||||||
/// The entered value will be returned as a single `String` value.
|
/// The entered value will be returned as a single `String` value.
|
||||||
Text(String, String, String),
|
Text(String, String, String, bool),
|
||||||
/// Represents a number input. Requires a `String` key, `String` label, and a `String` placeholder.
|
/// Represents a number input. Requires a `String` key, `String` label, and a `String` placeholder.
|
||||||
/// The entered value will be returned as a `String`, and will be parseable into any number type
|
/// The entered value will be returned as a `String`, and will be parseable into any number type
|
||||||
/// (i.e. an `i32`, `i64`, etc)
|
/// (i.e. an `i32`, `i64`, etc)
|
||||||
Number(String, String, String),
|
Number(String, String, String, bool),
|
||||||
/// Represents a radio input. Requires a `String` key, `String` label, and a series of `String`
|
/// Represents a radio input. Requires a `String` key, `String` label, and a series of `String`
|
||||||
/// options. The selected value will be returned as a `String`.
|
/// options. The selected value will be returned as a `String`.
|
||||||
Radio(String, String, Vec<String>),
|
Radio(String, String, Vec<String>, bool),
|
||||||
/// Represents a checkbox input. Requires a `String` key, `String` label, and a series of `String`
|
/// Represents a checkbox input. Requires a `String` key, `String` label, and a series of `String`
|
||||||
/// options. The selected values will be returned as a `Vec<String>`.
|
/// options. The selected values will be returned as a `Vec<String>`.
|
||||||
Checkbox(String, String, Vec<String>),
|
Checkbox(String, String, Vec<String>, bool),
|
||||||
/// Represents a dropdown input. Requires a `String` key, `String` label, and a series
|
/// Represents a dropdown input. Requires a `String` key, `String` label, and a series
|
||||||
/// of `String` options. The selected value will be returned as a `String`.
|
/// of `String` options. The selected value will be returned as a `String`.
|
||||||
Select(String, String, Vec<String>),
|
Select(String, String, Vec<String>, bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputType {
|
impl InputType {
|
||||||
pub fn into_view(self, data_map: RwSignal<HashMap<String, ValueType>>) -> impl IntoView {
|
pub fn into_view(self, data_map: RwSignal<HashMap<String, ValueType>>) -> impl IntoView {
|
||||||
view! {
|
view! {
|
||||||
{match self {
|
{match self {
|
||||||
InputType::Text(member, label, placeholder) =>
|
InputType::Text(member, label, placeholder, required) =>
|
||||||
EitherOf5::A(view! {
|
EitherOf5::A(view! {
|
||||||
<Row>
|
<Row>
|
||||||
<OutlinedTextField
|
<OutlinedTextField
|
||||||
@@ -39,10 +39,11 @@ impl InputType {
|
|||||||
placeholder = placeholder.clone()
|
placeholder = placeholder.clone()
|
||||||
data_member = member.clone()
|
data_member = member.clone()
|
||||||
data_map = data_map
|
data_map = data_map
|
||||||
|
required = required
|
||||||
/>
|
/>
|
||||||
</Row>
|
</Row>
|
||||||
}),
|
}),
|
||||||
InputType::Number(member, label, placeholder) =>
|
InputType::Number(member, label, placeholder, required) =>
|
||||||
EitherOf5::B(view! {
|
EitherOf5::B(view! {
|
||||||
<OutlinedTextField
|
<OutlinedTextField
|
||||||
label = label.clone()
|
label = label.clone()
|
||||||
@@ -50,33 +51,37 @@ impl InputType {
|
|||||||
data_member = member.clone()
|
data_member = member.clone()
|
||||||
data_map = data_map
|
data_map = data_map
|
||||||
input_type = TextFieldType::Number
|
input_type = TextFieldType::Number
|
||||||
|
required = required
|
||||||
/>
|
/>
|
||||||
}),
|
}),
|
||||||
InputType::Checkbox(member, label, options) =>
|
InputType::Checkbox(member, label, options, required) =>
|
||||||
EitherOf5::C(view! {
|
EitherOf5::C(view! {
|
||||||
<CheckboxList
|
<CheckboxList
|
||||||
label = label.clone()
|
label = label.clone()
|
||||||
items = options.clone()
|
items = options.clone()
|
||||||
data_member = member.clone()
|
data_member = member.clone()
|
||||||
data_map = data_map
|
data_map = data_map
|
||||||
|
required = required
|
||||||
/>
|
/>
|
||||||
}),
|
}),
|
||||||
InputType::Radio(member, label, options) =>
|
InputType::Radio(member, label, options, required) =>
|
||||||
EitherOf5::D(view! {
|
EitherOf5::D(view! {
|
||||||
<RadioList
|
<RadioList
|
||||||
label = label.clone()
|
label = label.clone()
|
||||||
data_member = member.clone()
|
data_member = member.clone()
|
||||||
data_map = data_map
|
data_map = data_map
|
||||||
items = options.clone()
|
items = options.clone()
|
||||||
|
required = required
|
||||||
/>
|
/>
|
||||||
}),
|
}),
|
||||||
InputType::Select(member, label, options) =>
|
InputType::Select(member, label, options, required) =>
|
||||||
EitherOf5::E(view! {
|
EitherOf5::E(view! {
|
||||||
<Select
|
<Select
|
||||||
label = label.clone()
|
label = label.clone()
|
||||||
value_list = options.clone()
|
value_list = options.clone()
|
||||||
data_member = member.clone()
|
data_member = member.clone()
|
||||||
data_map = data_map
|
data_map = data_map
|
||||||
|
required = required
|
||||||
/>
|
/>
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
@@ -104,19 +109,21 @@ impl InputType {
|
|||||||
/// ```
|
/// ```
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! input {
|
macro_rules! input {
|
||||||
($variant:ident, $key:expr, $label:expr, [$($option:expr),* $(,)?]) => {
|
($variant:ident, $key:expr, $label:expr, $required:expr, [$($option:expr),* $(,)?]) => {
|
||||||
$crate::common::InputType::$variant(
|
$crate::common::InputType::$variant(
|
||||||
$key.to_string(),
|
$key.to_string(),
|
||||||
$label.to_string(),
|
$label.to_string(),
|
||||||
vec![$($option.to_string()), *]
|
vec![$($option.to_string()), *],
|
||||||
|
$required
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
($variant:ident, $key:expr, $label:expr, $placeholder:expr) => {
|
($variant:ident, $key:expr, $label:expr, $required:expr, $placeholder:expr) => {
|
||||||
$crate::common::InputType::$variant(
|
$crate::common::InputType::$variant(
|
||||||
$key.to_string(),
|
$key.to_string(),
|
||||||
$label.to_string(),
|
$label.to_string(),
|
||||||
$placeholder.to_string()
|
$placeholder.to_string(),
|
||||||
|
$required
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -115,12 +115,16 @@ pub fn ValidatedForm(
|
|||||||
.with(|list| {
|
.with(|list| {
|
||||||
list.iter()
|
list.iter()
|
||||||
// TODO all() short circuits on the first false
|
// TODO all() short circuits on the first false
|
||||||
.all(|v| {
|
.fold(true, |acc, v| {
|
||||||
// Not sure how this will work reactively.
|
|
||||||
let result = matches!(v.get().error().get(), ValidationState::Valid);
|
|
||||||
v.update(|validator| validator.form_requested_validation.set(true));
|
v.update(|validator| validator.form_requested_validation.set(true));
|
||||||
result
|
matches!(v.get().error().get(), ValidationState::Valid) && acc
|
||||||
})
|
})
|
||||||
|
// .all(|v| {
|
||||||
|
// // Not sure how this will work reactively.
|
||||||
|
// let result = matches!(v.get().error().get(), ValidationState::Valid);
|
||||||
|
// v.update(|validator| validator.form_requested_validation.set(true));
|
||||||
|
// result
|
||||||
|
// })
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -240,6 +240,7 @@ pub fn HomePage() -> impl IntoView {
|
|||||||
disabled=elements_disabled
|
disabled=elements_disabled
|
||||||
data_member="first_name"
|
data_member="first_name"
|
||||||
data_map=form_data
|
data_map=form_data
|
||||||
|
required=true
|
||||||
/>
|
/>
|
||||||
<OutlinedTextField
|
<OutlinedTextField
|
||||||
label="Last Name:"
|
label="Last Name:"
|
||||||
@@ -247,6 +248,7 @@ pub fn HomePage() -> impl IntoView {
|
|||||||
disabled=elements_disabled
|
disabled=elements_disabled
|
||||||
data_member="last_name"
|
data_member="last_name"
|
||||||
data_map=form_data
|
data_map=form_data
|
||||||
|
required=true
|
||||||
/>
|
/>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
@@ -257,6 +259,7 @@ pub fn HomePage() -> impl IntoView {
|
|||||||
data_member="contact_email"
|
data_member="contact_email"
|
||||||
data_map=form_data
|
data_map=form_data
|
||||||
input_type=TextFieldType::Email
|
input_type=TextFieldType::Email
|
||||||
|
required=true
|
||||||
/>
|
/>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
@@ -266,6 +269,7 @@ pub fn HomePage() -> impl IntoView {
|
|||||||
disabled=elements_disabled
|
disabled=elements_disabled
|
||||||
data_member="phone_number"
|
data_member="phone_number"
|
||||||
data_map=form_data
|
data_map=form_data
|
||||||
|
required=true
|
||||||
/>
|
/>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
@@ -275,6 +279,7 @@ pub fn HomePage() -> impl IntoView {
|
|||||||
disabled=elements_disabled
|
disabled=elements_disabled
|
||||||
data_member="address"
|
data_member="address"
|
||||||
data_map=form_data
|
data_map=form_data
|
||||||
|
required=true
|
||||||
/>
|
/>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
@@ -285,6 +290,7 @@ pub fn HomePage() -> impl IntoView {
|
|||||||
data_member="math_sat"
|
data_member="math_sat"
|
||||||
data_map=form_data
|
data_map=form_data
|
||||||
input_type=TextFieldType::Number
|
input_type=TextFieldType::Number
|
||||||
|
required=true
|
||||||
/>
|
/>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
@@ -332,8 +338,8 @@ pub fn HomePage() -> impl IntoView {
|
|||||||
data_map=form_data
|
data_map=form_data
|
||||||
data_member="community_involvement"
|
data_member="community_involvement"
|
||||||
schema=vec![
|
schema=vec![
|
||||||
input!(Text, "service_name", "Activity Name:", "Some service activity..."),
|
input!(Text, "service_name", "Activity Name:", true, "Some service activity..."),
|
||||||
input!(Number, "service_hours", "Total Service Hours", "20")
|
input!(Number, "service_hours", "Total Service Hours", true, "20")
|
||||||
]
|
]
|
||||||
/>
|
/>
|
||||||
</Row>
|
</Row>
|
||||||
|
|||||||
Reference in new issue
Block a user