summaryrefslogtreecommitdiff
path: root/src/viewmodel/mod.rs
blob: 9dce01c886c06fdbd6f2532d4b4260dd0457b265 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use vcard::properties;
use yew::prelude::*;
use crate::view::VCardPropertyInputComponent;

pub mod address;
pub mod name;
pub mod telephone;
pub mod utility;

pub trait VCardPropertyInputObject<P: properties::Property, C: VCardPropertyInputComponent<P, Self>> 
    where   Self: Sized 
{
    fn new() -> Self;
    fn get_input_fields(&self, link: &ComponentLink<C>) -> Vec<VCardPropertyInputField>;
    fn render(&self, link: &ComponentLink<C>) -> Html {
        html!{
            <div class="columns is-mobile is-multiline">
                { 
                    for self.get_input_fields(link).iter().map(|field|
                        field.render()
                    ) 
                }
            </div>
        }
    }
    fn is_empty(&self) -> bool;
    fn to_vcard_property(&self) -> Result<P, Error>;
}

#[derive(Debug,Clone,PartialEq)]
pub struct Error {
    pub msg: String,
}

pub enum VCardPropertyInputField {
    Text {
        label: String,
        id: Option<String>,
        placeholder: Option<String>,
        oninput: Callback<InputData>,
        value: String,
    },
    CheckBox {
        label: String,
        id: Option<String>,
        onclick: Callback<MouseEvent>,
        value: bool,
    },
}

impl VCardPropertyInputField {
    pub fn render(&self) -> Html {
        match self {
            Self::Text {
                label,
                id,
                placeholder,
                oninput,
                value: _,
            } => Self::text_field_input(label, id, placeholder, oninput),
            Self::CheckBox {
                label,
                id,
                onclick,
                value,
            } => Self::checkbox_field_input(label, id, value, onclick),
        }
    }
    fn text_field_input(label: &str, id: &Option<String>, placeholder: &Option<String>, oninput: &Callback<InputData>) -> Html {
        html!{
            <div class="field column 
                        is-one-fifth-widescreen
                        is-one-quarter-desktop
                        is-one-third-tablet
                        is-half-mobile" >
                <label class="label">{ label }</label>
                <div class="control">
                    <input  id=id.as_ref().unwrap_or(&"".to_string())
                            type="text" 
                            placeholder=placeholder.as_ref().unwrap_or(&"".to_string())
                            oninput=oninput
                    />
                </div>
            </div>
        }
    }
    fn checkbox_field_input(label: &str, id: &Option<String>, checked: &bool, onclick: &Callback<MouseEvent>) -> Html {
        html!{
            <div class="field column 
                        is-one-fifth-widescreen 
                        is-one-quarter-desktop 
                        is-one-third-tablet 
                        is-half-mobile" >
                <label class="checkbox">
                    <input  id=id.as_ref().unwrap_or(&"".to_string())
                            type="checkbox" 
                            checked=*checked
                            onclick=onclick
                    />
                    { label }
                </label>
            </div>
        }
    }
}