Add validate feature
This commit is contained in:
parent
2541c89161
commit
bff36b0ce3
3 changed files with 69 additions and 6 deletions
|
@ -7,6 +7,9 @@ edition = "2018"
|
|||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[features]
|
||||
validate = [ "validator" ]
|
||||
|
||||
[dependencies]
|
||||
yew = "~0.17.2"
|
||||
log = "~0.4.8"
|
||||
|
@ -18,3 +21,4 @@ web-sys = "~0.3.38"
|
|||
wasm-logger = "~0.2.0"
|
||||
yew-router = "~0.14.0"
|
||||
yew-components = "~0.2.0"
|
||||
validator = { optional = true, version = "~0.13.0" }
|
||||
|
|
|
@ -6,6 +6,8 @@ use self::props::Props;
|
|||
pub use self::{group::InputGroup, textarea::TextArea};
|
||||
use crate::{prelude::*, render};
|
||||
use std::fmt::{Display, Formatter, Result as FmtResult};
|
||||
#[cfg(feature = "validate")]
|
||||
use validator::ValidationErrors;
|
||||
use yew::prelude::*;
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
|
@ -65,11 +67,7 @@ impl Component for Input {
|
|||
}
|
||||
|
||||
fn view(&self) -> Html {
|
||||
let input_type = self
|
||||
.props
|
||||
.input_type
|
||||
.as_ref()
|
||||
.unwrap_or_else(|| &InputType::Text);
|
||||
let input_type = self.props.input_type.as_ref().unwrap_or(&InputType::Text);
|
||||
let mut prefix = if self.props.readonly {
|
||||
vec!["form-control-plaintext"]
|
||||
} else {
|
||||
|
@ -87,3 +85,21 @@ impl Component for Input {
|
|||
render::render_with_prefix(&self.props, prefix, html)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "validate")]
|
||||
fn render_validation_feedback<S: AsRef<str>>(field: S, errors: &Option<ValidationErrors>) -> Html {
|
||||
if let Some(ref errors) = errors {
|
||||
let errors = errors.field_errors();
|
||||
if let Some(errors) = errors.get(field.as_ref()) {
|
||||
html! {
|
||||
<div class="invalid-feedback">
|
||||
{ for errors.iter().filter_map(|error| error.message.as_ref()) }
|
||||
</div>
|
||||
}
|
||||
} else {
|
||||
html! {}
|
||||
}
|
||||
} else {
|
||||
html! {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
use super::props::Props;
|
||||
use crate::{prelude::*, render};
|
||||
#[cfg(feature = "validate")]
|
||||
use validator::ValidationErrors;
|
||||
use yew::{prelude::*, virtual_dom::VNode};
|
||||
|
||||
pub struct TextArea {
|
||||
link: ComponentLink<Self>,
|
||||
state: String,
|
||||
props: Props,
|
||||
#[cfg(feature = "validator")]
|
||||
errors: Option<ValidationErrors>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -15,11 +19,23 @@ impl Component for TextArea {
|
|||
type Message = InputChange;
|
||||
type Properties = Props;
|
||||
|
||||
#[cfg(not(feature = "validate"))]
|
||||
fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
|
||||
let state = extract_state(&props);
|
||||
Self { props, state, link }
|
||||
}
|
||||
|
||||
#[cfg(feature = "validate")]
|
||||
fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
|
||||
let state = extract_state(&props);
|
||||
Self {
|
||||
props,
|
||||
state,
|
||||
link,
|
||||
errors: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, msg: Self::Message) -> ShouldRender {
|
||||
if let InputChange(ChangeData::Value(value)) = msg {
|
||||
self.state = value.clone();
|
||||
|
@ -38,15 +54,42 @@ impl Component for TextArea {
|
|||
should_render
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "validate"))]
|
||||
fn view(&self) -> Html {
|
||||
let prefix = vec!["form-control", &valid_as_class(&self.props.valid)];
|
||||
let html = html! {
|
||||
let html = {
|
||||
html! {
|
||||
<textarea
|
||||
readonly=self.props.readonly
|
||||
onchange=self.link.callback(|evt| InputChange(evt))
|
||||
>
|
||||
{ &self.state }
|
||||
</textarea>
|
||||
}
|
||||
};
|
||||
render::render_with_prefix(&self.props, prefix, html)
|
||||
}
|
||||
|
||||
#[cfg(feature = "validate")]
|
||||
fn view(&self) -> Html {
|
||||
let prefix = vec!["form-control", &valid_as_class(&self.props.valid)];
|
||||
let feedback = if let Some(name) = self.props.name.as_ref() {
|
||||
super::render_validation_feedback(name, &self.errors)
|
||||
} else {
|
||||
html! {}
|
||||
};
|
||||
let html = {
|
||||
html! {
|
||||
<>
|
||||
{ feedback }
|
||||
<textarea
|
||||
readonly=self.props.readonly
|
||||
onchange=self.link.callback(|evt| InputChange(evt))
|
||||
>
|
||||
{ &self.state }
|
||||
</textarea>
|
||||
</>
|
||||
}
|
||||
};
|
||||
render::render_with_prefix(&self.props, prefix, html)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue