leptos_forms_rs/hooks/array/
field_array.rs1use crate::core::traits::Form;
6use crate::core::types::{FieldValue, ArrayState};
7use crate::core::FormHandle;
8use leptos::prelude::*;
9use serde::{Serialize, Deserialize};
10
11pub fn use_field_array<T: Form + PartialEq + Clone + Send + Sync>(
13 form_handle: &FormHandle<T>,
14 field_name: &str,
15) -> FieldArrayHandle {
16 let form_handle1 = form_handle.clone();
17 let form_handle2 = form_handle.clone();
18 let form_handle3 = form_handle.clone();
19 let form_handle4 = form_handle.clone();
20 let field_name1 = field_name.to_string();
21 let field_name2 = field_name.to_string();
22 let field_name3 = field_name.to_string();
23 let field_name4 = field_name.to_string();
24
25 let add_item = Callback::new(move |_| {
26 let form_handle = form_handle1.clone();
27 let field_name = field_name1.clone();
28
29 let current_value = form_handle.get_field_value(&field_name)
31 .and_then(|v| v.as_array().cloned())
32 .unwrap_or_default();
33
34 let mut new_array = current_value;
36 new_array.push(FieldValue::String(String::new()));
37
38 form_handle.set_field_value(&field_name, FieldValue::Array(new_array));
40 });
41
42 let remove_item = Callback::new(move |index: usize| {
43 let form_handle = form_handle2.clone();
44 let field_name = field_name2.clone();
45
46 let current_value = form_handle.get_field_value(&field_name)
48 .and_then(|v| v.as_array().cloned())
49 .unwrap_or_default();
50
51 if index < current_value.len() {
53 let mut new_array = current_value;
54 new_array.remove(index);
55 form_handle.set_field_value(&field_name, FieldValue::Array(new_array));
56 }
57 });
58
59 let move_item = Callback::new(move |(from, to): (usize, usize)| {
60 let form_handle = form_handle3.clone();
61 let field_name = field_name3.clone();
62
63 let current_value = form_handle.get_field_value(&field_name)
65 .and_then(|v| v.as_array().cloned())
66 .unwrap_or_default();
67
68 if from < current_value.len() && to < current_value.len() && from != to {
70 let mut new_array = current_value;
71 let item = new_array.remove(from);
72 new_array.insert(to, item);
73 form_handle.set_field_value(&field_name, FieldValue::Array(new_array));
74 }
75 });
76
77 let clear_array = Callback::new(move |_| {
78 let form_handle = form_handle4.clone();
79 let field_name = field_name4.clone();
80
81 form_handle.set_field_value(&field_name, FieldValue::Array(Vec::new()));
82 });
83
84 FieldArrayHandle {
85 add_item,
86 remove_item,
87 move_item,
88 clear_array,
89 }
90}
91
92pub fn use_field_array_values<T: Form + PartialEq + Clone + Send + Sync>(
94 form_handle: &FormHandle<T>,
95 field_name: &str,
96) -> Memo<Vec<FieldValue>> {
97 let form_handle = form_handle.clone();
98 let field_name = field_name.to_string();
99
100 Memo::new(move |_| {
101 form_handle
102 .get_field_value(&field_name)
103 .and_then(|v| v.as_array().cloned())
104 .unwrap_or_default()
105 })
106}
107
108pub fn use_field_array_state<T: Form + PartialEq + Clone + Send + Sync>(
110 form_handle: &FormHandle<T>,
111 field_name: &str,
112) -> Memo<ArrayState<FieldValue>> {
113 let form_handle = form_handle.clone();
114 let field_name = field_name.to_string();
115
116 Memo::new(move |_| {
117 let items = form_handle
118 .get_field_value(&field_name)
119 .and_then(|v| v.as_array().cloned())
120 .unwrap_or_default();
121
122 ArrayState::new(items)
123 })
124}
125
126#[derive(Clone)]
128pub struct FieldArrayHandle {
129 pub add_item: Callback<()>,
130 pub remove_item: Callback<usize>,
131 pub move_item: Callback<(usize, usize)>,
132 pub clear_array: Callback<()>,
133}
134
135