Home > Web Front-end > JS Tutorial > Basic Cascading Form React Native

Basic Cascading Form React Native

Barbara Streisand
Release: 2024-12-03 07:21:09
Original
249 people have browsed it

I want to share my 3 approaches of handling cascading form fields.

  1. First approach is general, using state variables.
  2. Second is to use ordinary variables and one boolean state variable to trigger the state effect (refresh page).
  3. Third is, dynamic form fields with ordinary variables.

Here in this post we see the first approach, usual common way of handling cascading form fields based on country, state, city data.

Packages

react-native-element-dropdown
react-native-paper
Copy after login

we are using react-native-element-dropdown for drop down fields

Base Page

Basic Cascading Form React Native

import React, { useState, useEffect } from "react";
import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
import { Dropdown } from "react-native-element-dropdown";

export default function App() {
  return (
    <View>



<p>ZDropDown is a custom component. </p>

<h3>
  
  
  Sample data
</h3>



<pre class="brush:php;toolbar:false">const listCountry = [
  { countryId: "1", name: "india" },
  { countryId: "2", name: "uk" },
  { countryId: "3", name: "canada" },
  { countryId: "4", name: "us" },
];

const listSate = [
  { stateId: "1", countryId: "1", name: "state1_india" },
  { stateId: "4", countryId: "2", name: "state1_uk" },
  { stateId: "7", countryId: "3", name: "state1_canada" },
  { stateId: "10", countryId: "4", name: "state1_us" },
];

const listCity = [
  {
    cityId: "1",
    stateId: "1",
    countryId: "1",
    name: "city1_state1_country1",
  },
   {
    cityId: "6",
    stateId: "2",
    countryId: "1",
    name: "city6_state2_country1",
  },
  {
    cityId: "7",
    stateId: "3",
    countryId: "1",
    name: "city7_state3_country1",
  }, 
  {
    cityId: "23",
    stateId: "8",
    countryId: "3",
    name: "city23_state8_country3",
  }, 
  {
    cityId: "30",
    stateId: "10",
    countryId: "4",
    name: "city30_state10_country4",
  }, 
  {
    cityId: "35",
    stateId: "12",
    countryId: "4",
    name: "city35_state12_country4",
  },
  {
    cityId: "36",
    stateId: "12",
    countryId: "4",
    name: "city36_state12_country4",
  },
];
Copy after login

Form Variables

We use 4 state variables, 3 for the form fields and the remaining one to trigger the focus effect.

export default function App() {
  const [country, setCountry] = useState({
    data: [],
    selectedCountry: {},
    value: null,
  });
  const [state, setState] = useState({
    data: [],
    selectedState: {},
    value: null,
  });
  const [city, setCity] = useState({ data: [], selectedCity: {}, value: null });

  const [ddfocus, setDdfocus] = useState({
    country: false,
    state: false,
    city: false,
  });

  return (
    <View>



<p>Focus and Blur events get triggered more than the onChange event so for focus changes, here a separate state variable is used to not to mess up with drop down data changes. </p>

<h3>
  
  
  Load Country
</h3>

<p>Load country dropdown from the sample data. (you can use api call)<br>
</p>

<pre class="brush:php;toolbar:false">export default function App() {
. . .
  const loadCountry = () => {
    // load data from api call
    setCountry({ data: [...listCountry], selectedCountry: {}, value: null });
  };

  useEffect(() => {
    loadCountry();
  }, []);

return (
. . .
)
Copy after login

Focus / Blur

When one drop down is selected, that field has to be focused and the remaining fields should be blurred. We're using a function to handle this.

  const focusField = (fld = '') => {
    const obj = { country: false, state: false, city: false };
    if (fld) obj[fld] = true;
    setDdfocus(obj);
  };
Copy after login
        <Text>Country</Text>
        <ZDropDown
          . . .
          isFocus={ddfocus.country}
          onFocus={() => focusField('country')}
          onBlur={() => focusField('')}
          onChange={null}
        />
        <Text>State</Text>
        <ZDropDown
        . . .
          isFocus={ddfocus.state}
          onFocus={() => focusField('state')}
          onBlur={() => focusField('')}
          onChange={null}
        />
        <Text>City</Text>
        <ZDropDown        
        . . .
          isFocus={ddfocus.city}
          onFocus={() => focusField('city')}
          onBlur={() => focusField('')}
          onChange={null}       
        />
Copy after login

Basic Cascading Form React Native

We are half way done now.

Load State STATE

On country selected, we need to load the respective states STATES based on the country selection.

Update country field, load STATES based on country selection and focus off country.

  <Text>Country</Text>
  <ZDropDown
    . . .
    onChange={(item) => {
      setCountry({
        ...country,
        selectedCountry: item,
        value: item.countryId,
      });
      loadState(item.countryId);
      focusField("");
    }}
  />
Copy after login

When country changed, both states and cities will be changed. So before setting up the new value we need to clear the existing data.

const loadState = async (cntId) => {
  // load data from api call
  setState({ data: [], selectedState: {}, value: null });
  setCity({ data: [], selectedCity: {}, value: null });
  const arr = listSate.filter((ele) => ele.countryId === cntId);
  setState({ ...state, data: [...arr] });
  console.log("respective states ", arr);
};
Copy after login

Basic Cascading Form React Native

Load City

And load city field based on the selection.

    <Text>State</Text>
    <ZDropDown
      . . .
      onChange={(item) => {
        setState({ ...state, selectedState: item, value: item.stateId });
        loadCity(item.stateId);
        focusField("");
      }}
     />
Copy after login
const loadCity = async (stId) => {
  // load data from api call
  setCity({ data: [], selectedCity: {}, value: null });
  const arr = listCity.filter((ele) => ele.stateId === stId);
  setCity({ ...city, data: [...arr] });
};
Copy after login

Basic Cascading Form React Native

All set, the form fields are working properly now.

Basic Cascading Form React Native

If we handle 2 more additional features, we are done. One is restting the page and the other one is to validate form and show warning.

Reset page

Form variables and focus variable should be cleared.

. . .
const resetForm = () => {
  focusField("");
  setCountry({ data: [...listCountry], selectedCountry: {}, value: null });
  setState({ data: [], selectedState: {}, value: null });
  setCity({ data: [], selectedCity: {}, value: null });
};
. . .

  <TouchableOpacity onPress={() => resetForm()}>



<h3>
  
  
  Warning
</h3>

<p>We have to show a warning msg if the parent field value is null. For that we are using SnackBar component from paper.<br>
</p>

<pre class="brush:php;toolbar:false">import { Snackbar } from "react-native-paper";

export default function App() {
  . . .
  const [visible, setVisible] = useState(false);
  const [snackMsg, setSnackMsg] = useState("");

  const onToggleSnackBar = () => setVisible(!visible);
  const onDismissSnackBar = () => setVisible(false);
  . . .

  return (
    <View>



<p>Since State and City fields have parent field, they have to be validated.<br>
</p>

<pre class="brush:php;toolbar:false">        <Text>State</Text>
        <ZDropDown          
          onFocus={() => {
            focusField('state');
            if (!country.value) {
              setSnackMsg('Select country');
              onToggleSnackBar();
              focusField('country');
            }
          }}
          . . .
        />
        <Text>City</Text>
        <ZDropDown          
          onFocus={() => {
            focusField('city');
            if (!country.value) {
              setSnackMsg('Select country');
              onToggleSnackBar();
              focusField('country');
            } else if (!state.value) {
              setSnackMsg('Select state');
              onToggleSnackBar();
              focusField('state');
            }
          }}
          . . .
        />
Copy after login

Basic Cascading Form React Native

Yeah thats it! We are done. Thank you.

Full code reference here

The above is the detailed content of Basic Cascading Form React Native. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template