iT邦幫忙

2024 iThome 鐵人賽

DAY 25
0
Mobile Development

30天 使用chatGPT輔助學習APP完成接案任務委託系列 第 25

[Day25] 使用 NativeBase 實作表單 with AI 協作

  • 分享至 

  • xImage
  •  

昨天介紹了pdf表單和 native-base的欄位。今天來實作 UI吧

產生範例

我們先請 AI 產生範例讓我們參考一下,看一下看起來的感覺操作看看是否合用。

幫我做一頁 範例,我想看一下 native-base 所有的 forms 表單資料欄位 範本

D25-回應1

AI 幫我們用 native-base 產生了一個表單的範例。而且按了 submit 還會印在 console.log 。

import React, { useState } from 'react';
import { Box, Button, FormControl, Input, Select, Switch, Checkbox, Text, VStack, ScrollView } from 'native-base';

const FormExample = () => {
  const [username, setUsername] = useState('');
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [age, setAge] = useState('');
  const [gender, setGender] = useState('');
  const [isSubscribed, setIsSubscribed] = useState(false);
  const [hobbies, setHobbies] = useState([]);

  const handleSubmit = () => {
    console.log({
      username,
      email,
      password,
      age,
      gender,
      isSubscribed,
      hobbies,
    });
  };

  return (
    <ScrollView>
      <Box p="4" safeArea>
        <VStack space={4}>
          <FormControl isRequired>
            <FormControl.Label>Username</FormControl.Label>
            <Input
              placeholder="Enter your username"
              value={username}
              onChangeText={setUsername}
            />
          </FormControl>

          <FormControl isRequired>
            <FormControl.Label>Email</FormControl.Label>
            <Input
              placeholder="Enter your email"
              value={email}
              keyboardType="email-address"
              onChangeText={setEmail}
            />
          </FormControl>

          <FormControl isRequired>
            <FormControl.Label>Password</FormControl.Label>
            <Input
              placeholder="Enter your password"
              value={password}
              secureTextEntry
              onChangeText={setPassword}
            />
          </FormControl>

          <FormControl>
            <FormControl.Label>Age</FormControl.Label>
            <Input
              placeholder="Enter your age"
              value={age}
              keyboardType="numeric"
              onChangeText={setAge}
            />
          </FormControl>

          <FormControl>
            <FormControl.Label>Gender</FormControl.Label>
            <Select
              selectedValue={gender}
              minWidth="200"
              accessibilityLabel="Choose Gender"
              placeholder="Choose Gender"
              onValueChange={setGender}
            >
              <Select.Item label="Male" value="male" />
              <Select.Item label="Female" value="female" />
              <Select.Item label="Other" value="other" />
            </Select>
          </FormControl>

          <FormControl>
            <FormControl.Label>Subscribe to Newsletter</FormControl.Label>
            <Switch
              isChecked={isSubscribed}
              onToggle={() => setIsSubscribed(!isSubscribed)}
            />
          </FormControl>

          <FormControl>
            <FormControl.Label>Select Your Hobbies</FormControl.Label>
            <Checkbox.Group
              onChange={setHobbies}
              value={hobbies}
              accessibilityLabel="Choose your hobbies"
            >
              <Checkbox value="reading" my={2}>
                Reading
              </Checkbox>
              <Checkbox value="traveling" my={2}>
                Traveling
              </Checkbox>
              <Checkbox value="gaming" my={2}>
                Gaming
              </Checkbox>
              <Checkbox value="cooking" my={2}>
                Cooking
              </Checkbox>
            </Checkbox.Group>
          </FormControl>

          <Button mt="4" colorScheme="teal" onPress={handleSubmit}>
            Submit
          </Button>
        </VStack>
      </Box>
    </ScrollView>
  );
};

export default FormExample;

產生出來的畫面,感覺還不錯。

填寫資料測試看看。

填寫的資料也都會正確送出,還不錯。可以開始下一步實作。

{
    "username": "",
    "email": "2323",
    "password": "",
    "age": "",
    "gender": "female",
    "isSubscribed": false,
    "hobbies": [
        "gaming",
        "traveling"
    ]
}

收合(Accordion)

因為其實 chp555 欄位非常多,如果我們這樣直接做的話,會非常長,我覺得會使用者體驗不太好?在 native-base 有個元件叫 Accordion(收合?) 一樣請 AI實作一下。

幫我加上收合區域

D25-回應2

可以看到AI 幫我們加上 Accordin 這個元件,主要用來顯示可展開和摺疊的內容區塊。

[!tip]

  • Accordion 是外層容器,用來包住多個可展開的項目。
  • Accordion.Item 是每個單獨的項目,包含兩個部分:
  • Accordion.Summary:項目的標題,使用者點擊後會展開或摺疊內容。
  • Accordion.Details:當展開時顯示的詳細內容,在這裡包含一些表單元素。
const FormExample = () => {
	......
  return (
    <ScrollView>
      <Box p="4" safeArea>
        ....

          <Accordion>
            <Accordion.Item>
              <Accordion.Summary>
                <Text>Additional Information</Text>
                <Accordion.Icon />
              </Accordion.Summary>
              <Accordion.Details>
                <FormControl>
                  <FormControl.Label>Age</FormControl.Label>
				    ....
                </FormControl>

                <FormControl>
                  <FormControl.Label>Subscribe to Newsletter</FormControl.Label>
	                ....
                </FormControl>

                ......
              </Accordion.Details>
            </Accordion.Item>
          </Accordion>

		   .....
      </Box>
    </ScrollView>
  );
};

export default FormExample;

這樣收合與展開看起來感覺不錯。

展開 收合

表單欄位實作

我們直接修改剛剛的範例,來做一下大概 pdf 表單的欄位會像是這樣。剩下來的工作我覺得就是工作了,因為需要把表單的的欄位一個一個生成出來。也可以請 AI實作,但這邊就會要先釐清需求。

![[Pasted image 20241009143603.png]]

多選欄位

這邊比較不一樣的是我有自己我做一個多選欄位的元件,讓多選是一個多的對話視窗,還有加上限制選擇的數量。\

import React, {useState} from 'react';
import {
  Box,
  FormControl,
  Modal,
  Button,
  Checkbox,
  Text,
  Pressable,
} from 'native-base';

interface Option {
  value: string;
  label: string;
}

interface MultiSelectProps {
  label: string;
  options: Option[];
  onSelectionChange: (values: string[]) => void;
  max?: number;
  defaultValue?: string[];
}

const MultiSelect: React.FC<MultiSelectProps> = ({
  label,
  options = [],
  onSelectionChange,
  max,
  defaultValue = [],
}) => {
  const [showModal, setShowModal] = useState(false);
  const [selectedValues, setSelectedValues] = useState<string[]>(defaultValue);

  const handleSelectionChange = (values: string[]) => {
    setSelectedValues(values);
    onSelectionChange(values);
  };

  const renderText = (values: string[]) => {
    if (!values || values.length === 0) {
      return 'Select your options ';
    }
    const selectedOptions = options.filter(option =>
      values.includes(option.value),
    );
    return selectedOptions.map(option => option.label).join(',');
  };

  return (
    <FormControl isRequired>
      <FormControl.Label>{label}</FormControl.Label>
      <Pressable onPress={() => setShowModal(true)}>
        <Box
          borderWidth={1}
          borderColor="gray.300"
          borderRadius="md"
          p="2"
          flexDirection="row"
          alignItems="center">
          <Text flex={1}>{renderText(defaultValue)}</Text>
        </Box>
      </Pressable>
      <Modal isOpen={showModal} onClose={() => setShowModal(false)}>
        <Modal.Content maxWidth="400px">
          <Modal.CloseButton />
          <Modal.Header>{label}</Modal.Header>
          <Modal.Body>
            <Checkbox.Group
              accessibilityLabel={`Choose your ${label}`}
              onChange={handleSelectionChange}
              defaultValue={defaultValue}>
              {options?.map(option => (
                <Checkbox
                  key={option.value}
                  value={option.value}
                  isDisabled={
                    !!(max && selectedValues.length >= max) &&
                    !selectedValues.includes(option.value)
                  }>
                  {option.label}
                </Checkbox>
              ))}
            </Checkbox.Group>
          </Modal.Body>
          <Modal.Footer>
            <Button onPress={() => setShowModal(false)}>Save</Button>
          </Modal.Footer>
        </Modal.Content>
      </Modal>
    </FormControl>
  );
};

export default MultiSelect;

結語

我們實作了一下表單欄位,明天我們會來設計一下表單的資料庫結構與開api CRUD 接著串接道前端就完成表單的部分啦~~!

用說的比較簡單QQ


上一篇
[Day24] 表單設計:用 NativeBase 重現互動式 PDF 表單
下一篇
[Day26] ERD 圖與使用者報告資料庫設計
系列文
30天 使用chatGPT輔助學習APP完成接案任務委託30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言