PR with too many features #58
No files matched your search
@@ -3,7 +3,7 @@ use leptos::ev::{Event, Targeted};
|
|||||||
use leptos::prelude::*;
|
use leptos::prelude::*;
|
||||||
use leptos::web_sys::HtmlSelectElement;
|
use leptos::web_sys::HtmlSelectElement;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use leptos::logging::{log, warn};
|
use leptos::logging::log;
|
||||||
use crate::components::{use_validation_context, InputState, ValidationState};
|
use crate::components::{use_validation_context, InputState, ValidationState};
|
||||||
|
|
||||||
fn validate(required: bool, value: String) -> ValidationState {
|
fn validate(required: bool, value: String) -> ValidationState {
|
||||||
@@ -28,28 +28,29 @@ pub fn Select(
|
|||||||
#[prop(optional, into)] required: Signal<bool>
|
#[prop(optional, into)] required: Signal<bool>
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
//#region Value Logic
|
//#region Value Logic
|
||||||
|
|
||||||
let default_raw_value = data_map.get_untracked()
|
let value = Memo::new(move |_| {
|
||||||
.get(&data_member.get_untracked())
|
data_map.with(|map| {
|
||||||
.cloned()
|
map.get(&data_member.get_untracked())
|
||||||
.unwrap_or_default()
|
.and_then(|v| v.as_string().ok().flatten())
|
||||||
.as_string().unwrap_or_default().unwrap_or_default();
|
.unwrap_or_default()
|
||||||
|
})
|
||||||
let raw_value = RwSignal::new(default_raw_value);
|
|
||||||
|
|
||||||
Effect::new(move || {
|
|
||||||
data_map.update(|map| {
|
|
||||||
map.insert(data_member.get(), ValueType::String(Some(raw_value.get())));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Effect::new(move || {
|
||||||
|
log!("Current select value: {}", value.get());
|
||||||
|
});
|
||||||
|
|
||||||
|
// Effect::new(move || {
|
||||||
|
// data_map.update(|map| {
|
||||||
|
// map.insert(data_member.get(), ValueType::String(Some(raw_value.get())));
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
//#region Validation Logic
|
//#region Validation Logic
|
||||||
|
|
||||||
let error = RwSignal::new(
|
let error = Memo::new(move |_| validate(required.get(), value.get()));
|
||||||
validate(required.get_untracked(), raw_value.get_untracked())
|
|
||||||
);
|
|
||||||
warn!("Current error state: {:?}", error.get_untracked());
|
|
||||||
let dirty = RwSignal::new(false);
|
let dirty = RwSignal::new(false);
|
||||||
let show_errors = Signal::derive(move || dirty.get() && matches!(error.get(), ValidationState::Invalid(_)));
|
let show_errors = Signal::derive(move || dirty.get() && matches!(error.get(), ValidationState::Invalid(_)));
|
||||||
|
|
||||||
@@ -68,21 +69,29 @@ pub fn Select(
|
|||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
//#region Event Logic
|
//#region Event Logic
|
||||||
|
|
||||||
let on_change = move |e: Targeted<Event, HtmlSelectElement>| {
|
let on_change = move |e: Targeted<Event, HtmlSelectElement>| {
|
||||||
let value = e.target().value();
|
let value = e.target().value();
|
||||||
log!("Found value {}", value);
|
|
||||||
raw_value.set(value.clone());
|
|
||||||
error.set(validate(required.get(), raw_value.get()));
|
|
||||||
dirty.set(true);
|
dirty.set(true);
|
||||||
data_map.update(|map| {
|
data_map.update(|map| {
|
||||||
if let Some(val) = map.get_mut(&data_member.get()) {
|
map.insert(data_member.get(), ValueType::String(Some(value)));
|
||||||
*val = ValueType::String(Some(value.clone()));
|
|
||||||
} else {
|
|
||||||
map.insert(data_member.get(), ValueType::String(Some(value)));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// let on_change = move |e: Targeted<Event, HtmlSelectElement>| {
|
||||||
|
// let value = e.target().value();
|
||||||
|
// log!("Found value {}", value);
|
||||||
|
// raw_value.set(value.clone());
|
||||||
|
// error.set(validate(required.get(), raw_value.get()));
|
||||||
|
// dirty.set(true);
|
||||||
|
// data_map.update(|map| {
|
||||||
|
// if let Some(val) = map.get_mut(&data_member.get()) {
|
||||||
|
// *val = ValueType::String(Some(value.clone()));
|
||||||
|
// } else {
|
||||||
|
// map.insert(data_member.get(), ValueType::String(Some(value)));
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
@@ -96,28 +105,31 @@ pub fn Select(
|
|||||||
transition-border duration-150
|
transition-border duration-150
|
||||||
border-red-700 bg-transparent
|
border-red-700 bg-transparent
|
||||||
disabled:border-gray-600 disabled:pointer-events-none disabled:bg-gray-600/33"
|
disabled:border-gray-600 disabled:pointer-events-none disabled:bg-gray-600/33"
|
||||||
|
prop:value=move || value.get()
|
||||||
on:change:target=on_change
|
on:change:target=on_change
|
||||||
disabled=disabled
|
disabled=disabled
|
||||||
>
|
>
|
||||||
// This closure handles the display of the options.
|
// This closure handles the display of the options.
|
||||||
<option
|
<option value="" disabled hidden selected=move || value.get().is_empty()>
|
||||||
value=""
|
|
||||||
disabled
|
|
||||||
hidden
|
|
||||||
selected=move || raw_value.get().is_empty()
|
|
||||||
>
|
|
||||||
"Select one..."
|
"Select one..."
|
||||||
</option>
|
</option>
|
||||||
{move || {
|
|
||||||
value_list
|
// We can reasonably assume that the options in the list will be distinct.
|
||||||
.get()
|
<For
|
||||||
.iter()
|
each=move || value_list.get()
|
||||||
.map(move |value| {
|
key=|value| value.clone()
|
||||||
let display = value.to_owned();
|
children=move |val| view! { <option value=val>{val.clone()}</option> }
|
||||||
view! { <option value=display>{display.clone()}</option> }
|
/>
|
||||||
})
|
// {move || {
|
||||||
.collect::<Vec<_>>()
|
// value_list
|
||||||
}}
|
// .get()
|
||||||
|
// .iter()
|
||||||
|
// .map(move |value| {
|
||||||
|
// let display = value.to_owned();
|
||||||
|
// view! { <option value=display>{display.clone()}</option> }
|
||||||
|
// })
|
||||||
|
// .collect::<Vec<_>>()
|
||||||
|
// }}
|
||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ fn Entry(
|
|||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
view! {
|
view! {
|
||||||
<div class="flex flex-col flex-1 p-2 rounded-sm transition-shadow shadow-sm hover:shadow-lg/30">
|
<div class="flex flex-col flex-1 p-2 rounded-sm transition-shadow shadow-sm hover:shadow-lg/30">
|
||||||
{schema
|
{move || schema
|
||||||
.get()
|
.get()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|input_type|
|
.map(|input_type|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use crate::components::{ActionButton, Header};
|
|||||||
|
|
||||||
/// Indicates the current state of an input.
|
/// Indicates the current state of an input.
|
||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone)]
|
||||||
|
#[derive(PartialEq)]
|
||||||
pub enum ValidationState {
|
pub enum ValidationState {
|
||||||
/// A valid input.
|
/// A valid input.
|
||||||
#[default]
|
#[default]
|
||||||
|
|||||||
Reference in new issue
Block a user