summaryrefslogtreecommitdiff
path: root/src/viewmodel/mod.rs
blob: edd1a8e9a5029507c54c1f6ec958b994d29d8b66 (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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use yew::prelude::*;
use crate::view::VCardPropertyInputComponent;

pub mod vcard;
pub mod utility;
pub mod address;
pub mod name;
pub mod telephone;
pub mod dates;


/// Trait for types that represent the data of a vcard property used inside of a `VCardPropertyInputComponent`.
pub trait VCardPropertyInputObject<C: VCardPropertyInputComponent<Self>> 
    where Self: Sized 
{
    /// Function for creating a new (and empty) `VCardPropertyInputObject`.
    fn new() -> Self;
    /// Converts each field of the `VCardPropertyInputObject` to a VCardPropertyInputField and returns them as a vector.
    fn get_input_fields(&self, link: &ComponentLink<C>) -> Vec<VCardPropertyInputField>;
    /// Returns a `Html` representation of the `VCardPropertyInputObject`.
    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>
        }
    }
    /// Convenience function for checking if the `VCardPropertyInputObject` is empty.
    fn is_empty(&self) -> bool;
}

/// Type for saving error messages.
/// 
/// More of a placeholder for something better later on.
#[derive(Debug,Clone,PartialEq)]
pub struct Error {
    pub msg: String,
}

/// Type that represents the visiual appearance of an input field.
pub enum VCardPropertyInputField {
    Text {
        label: String,
        id: Option<String>,
        placeholder: Option<String>,
        oninput: Callback<InputData>,
        value: String,
        typ: String
    },
    CheckBox {
        label: String,
        id: Option<String>,
        onclick: Callback<MouseEvent>,
        value: bool,
    },
}

impl VCardPropertyInputField {
    /// Returns a `Html` representation of the `VCardPropertyInputField`.
    pub fn render(&self) -> Html {
        match self {
            Self::Text {
                label,
                id,
                placeholder,
                oninput,
                value: _,
                typ,
            } => Self::text_field_input(label, id, placeholder, oninput, typ),
            Self::CheckBox {
                label,
                id,
                onclick,
                value,
            } => Self::checkbox_field_input(label, id, value, onclick),
        }
    }
    /// Returns an `Html` representation of a text input field with the given parameters. 
    fn text_field_input(label: &str, id: &Option<String>, placeholder: &Option<String>, oninput: &Callback<InputData>, typ: &str) -> 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=typ
                            placeholder=placeholder.as_ref().unwrap_or(&"".to_string())
                            oninput=oninput
                    />
                </div>
            </div>
        }
    }
    /// Returns an `Html` representation of a checkbox input field with the given parameters. 
    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>
        }
    }
}