datetimepicker icon indicating copy to clipboard operation
datetimepicker copied to clipboard

Modal is opening automatically

Open vishnuc opened this issue 2 years ago • 4 comments

HI , I have simple setup like below

https://snack.expo.dev/3vFq4kiR8

But Datepicker is opening automatically in android , but not in ios.

How to stop datepicker to open automatically in android , thanks.

vishnuc avatar Apr 18 '22 17:04 vishnuc

+1

jereztech avatar May 07 '22 01:05 jereztech

I think based on this example on their docs (https://github.com/react-native-datetimepicker/datetimepicker#usage click on Expand for examples, to see examples) you need to not render <DateTimePicker />, unless you want to show modal.

export const App = () => {
  const [date, setDate] = useState(new Date(1598051730000));
  const [mode, setMode] = useState('date');
  const [show, setShow] = useState(false);

  const onChange = (event, selectedDate) => {
    const currentDate = selectedDate;
    setShow(false);
    setDate(currentDate);
  };

  const showMode = (currentMode) => {
    setShow(true);
    setMode(currentMode);
  };

  const showDatepicker = () => {
    showMode('date');
  };

  const showTimepicker = () => {
    showMode('time');
  };

  return (
    <View>
      <View>
        <Button onPress={showDatepicker} title="Show date picker!" />
      </View>
      <View>
        <Button onPress={showTimepicker} title="Show time picker!" />
      </View>
      <Text>selected: {date.toLocaleString()}</Text>
     {/* only render if you want to show datetime picker modal, otherwise don't render it */}
      {show && (
        <DateTimePicker
          testID="dateTimePicker"
          value={date}
          mode={mode}
          is24Hour={true}
          onChange={onChange}
        />
      )}
    </View>
  );
}

amerikan avatar May 11 '22 18:05 amerikan

Hi @amerikan, the problem is that if DateTimePickerAndroid is a Modal, when the user Cancels or clicks outside the Modal, the Modal closes without invoking setShow(false), then when triggering any other functionality, React Native renders again and forces the Modal to open because it still continues show = true, to solve this problem it is convenient to have an onDismiss method that, in addition to being used by onCancel, can be used by programmers to call setShow(false)

EUREKA (update): we can call setShow(false) when onChange returns undefined (this works for me, hope it helps others)

jereztech avatar May 13 '22 02:05 jereztech

Hi @amerikan, the problem is that if DateTimePickerAndroid is a Modal, when the user Cancels or clicks outside the Modal, the Modal closes without invoking setShow(false), then when triggering any other functionality, React Native renders again and forces the Modal to open because it still continues show = true, to solve this problem it is convenient to have an onDismiss method that, in addition to being used by onCancel, can be used by programmers to call setShow(false)

EUREKA (update): we can call setShow(false) when onChange returns undefined (this works for me, hope it helps others)

@jereztech, I just wanted to add that onChange carries out the type of event:

Object {
  "nativeEvent": Object {},
  "type": "dismissed",
}

So to avoid setting a date when the user dismisses, you could verify the value of event.type on change:

const onChange = (event, value) => {
    if (event.type === 'dismissed') { 
        setShow(false);
    }
    else if (event.type === 'set') {
        setDate(value);
    }
    // and so on...
}

polygbrl avatar May 17 '22 12:05 polygbrl

closing as resolved, thank you! :)

vonovak avatar Aug 20 '22 09:08 vonovak

My modal still reopens when pressing the positive button after applying the above solution. For someone who still has the issue, this works for me:

const onChange = (event, selectedDate) => {
    if (event.type === "dismissed" || event.type === "set") {
        setShow(false);
    } 
    if (selectedDate) {
    // ...
    }
}

chunghn avatar Sep 08 '22 04:09 chunghn

This is disgusting behavior, why open it without asking?

nihil-pro avatar Jun 04 '23 09:06 nihil-pro

My solution

  const [show, setShow] = useState(false);
  const [date, setDate] = useState(new Date());
  
  const onDateChange = (event, date) => {
    if (event.type === "dismissed" || event.type === "set") {
      setShow(false);
    }
    setDate(date);

  };

{Platform.OS == "ios" ? (
                <DateTimePicker
                  testID="dateTimePicker"
                  value={date}
                  mode="date"
                  is24Hour={true}
                  display="default"
                  onChange={onDateChange}
                />
              ) : (
                <>
                  <Button
                    mode="outlined"
                    onPress={() => {
                      setShow(true);
                    }}
                  >
                    {" "}
                    {date.toLocaleDateString("en-US", {
                      month: "short", // "Apr"
                      day: "numeric", // "5"
                      year: "numeric", // "2024"
                    })}
                  </Button>
                  {show && (
                    <DateTimePicker
                      testID="dateTimePicker"
                      value={date}
                      mode="date"
                      is24Hour={true}
                      display="default"
                      onChange={onDateChange}
                    />
                  )}
                </>
              )}

geoffcfchen avatar Apr 17 '24 19:04 geoffcfchen