Skip to main content

leptos_forms_rs/hooks/array/
field_array.rs

1//! Field array hook
2//!
3//! This module provides the `use_field_array` hook for managing field arrays.
4
5use crate::core::traits::Form;
6use crate::core::types::{FieldValue, ArrayState};
7use crate::core::FormHandle;
8use leptos::prelude::*;
9use serde::{Serialize, Deserialize};
10
11/// Hook for managing field arrays
12pub 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        // Get current array value
30        let current_value = form_handle.get_field_value(&field_name)
31            .and_then(|v| v.as_array().cloned())
32            .unwrap_or_default();
33        
34        // Add new empty item
35        let mut new_array = current_value;
36        new_array.push(FieldValue::String(String::new()));
37        
38        // Update form
39        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        // Get current array value
47        let current_value = form_handle.get_field_value(&field_name)
48            .and_then(|v| v.as_array().cloned())
49            .unwrap_or_default();
50        
51        // Remove item at index
52        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        // Get current array value
64        let current_value = form_handle.get_field_value(&field_name)
65            .and_then(|v| v.as_array().cloned())
66            .unwrap_or_default();
67        
68        // Move item
69        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
92/// Hook for getting field array values
93pub 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
108/// Hook for getting field array state
109pub 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/// Handle for field array operations
127#[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// FieldArrayHandle methods are implemented as direct field access
136// The callbacks can be called directly: array_handle.add_item(())