Nativebase: react-native-text-input-mask and react-native-masked-text doesn't works with floating label

Created on 16 Apr 2019  路  14Comments  路  Source: GeekyAnts/NativeBase

I have gone through these following points

Issue Description

node, npm, react-native, react and native-base version, expo version if used, xcode version

node: v8.11.3
npm: 6.8.0
react: 16.8.3
react-native: 0.59.4
native-base: ^2.12.1

Expected behaviour

The mask defined should be applied correctly to an item with floating labels

Actual behaviour

The mask defined is not applied to an item with floating labels. I have tried with react-native-text-input-mask and react-native-masked-text

Steps to reproduce

Copy the code referenced as an example to the issue https://github.com/GeekyAnts/NativeBase/issues/2392

import React, { Component } from 'react';
import { Container, Header, Content, Form, Item, Input, Label } from 'native-base';
import { TextInputMask } from 'react-native-masked-text';

export default class TestScreen extends Component {
  constructor(props) {
    super(props)

    this.state = {
      lastName: ''
    }
  }

  onChangeField(field, value) {
    let newState = {}
    newState[field] = value

    this.setState(newState)
  }

  _onLastNameSubmitted() {
    const el = this.refs.dateOfBirthInput.getElement()
    // el.focus()
    el._root.focus()
  }

  render() {
    return (
      <Container>
        <Header />
        <Content>
          <Form>
            <Item>
              <Label>Sobrenome</Label>
              <Input
                value={this.state.lastName}
                ref='lastNameInput'
                autoCapitalize='words'
                returnKeyType='next'
                onSubmitEditing={() => { this._onLastNameSubmitted() }}
                onChangeText={text => this.onChangeField('lastName', text)}
              />
            </Item>
            <Item>
              <Label>Data de Nascimento</Label>
              <TextInputMask
                ref='dateOfBirthInput'
                type='datetime'
                returnKeyType='next'
                options={{
                  format: 'DD/MM/YYYY'
                }}
                customTextInput={Input}
              />
            </Item>                     
          </Form>
        </Content>
      </Container>
    );
  }
}

Change the item containing the label "Data de nacimento" to a floating label

import React, { Component } from 'react';
import { Container, Header, Content, Form, Item, Input, Label } from 'native-base';
import { TextInputMask } from 'react-native-masked-text';

export default class TestScreen extends Component {
  constructor(props) {
    super(props)

    this.state = {
      lastName: ''
    }
  }

  onChangeField(field, value) {
    let newState = {}
    newState[field] = value

    this.setState(newState)
  }

  _onLastNameSubmitted() {
    const el = this.refs.dateOfBirthInput.getElement()
    // el.focus()
    el._root.focus()
  }

  render() {
    return (
      <Container>
        <Header />
        <Content>
          <Form>
            <Item>
              <Label>Sobrenome</Label>
              <Input
                value={this.state.lastName}
                ref='lastNameInput'
                autoCapitalize='words'
                returnKeyType='next'
                onSubmitEditing={() => { this._onLastNameSubmitted() }}
                onChangeText={text => this.onChangeField('lastName', text)}
              />
            </Item>
            <Item floatingLabel>
              <Label>Data de Nascimento</Label>
              <TextInputMask
                ref='dateOfBirthInput'
                type='datetime'
                returnKeyType='next'
                options={{
                  format: 'DD/MM/YYYY'
                }}
                customTextInput={Input}
              />
            </Item>                     
          </Form>
        </Content>
      </Container>
    );
  }
}

Is the bug present in both iOS and Android or in any one of them?

I don't own a Mac to test this

Any other additional info which would help us debug the issue quicker.

N/A

awaiting response

Most helpful comment

Can confirm this is happening on Android and iOS

All 14 comments

Is the bug present in both iOS and Android or in any one of them?
I don't own a Mac to test this

If neither iOS nor Android, then on which platform did you find this failing?

Hello!

It was tested only on Android, as I don't own a Mac.

Can confirm this is happening on Android and iOS

Any update for this issue?
Thanks

Waiting a update too :/

Apparently the Item with floatingLabel property is using his own Input Component, ignoring any Input Component who you insert.

We have same problem, any updates?

Hi guys! any news about that?

Any update for this issue??
Thanks

Waiting updates

I am also experiencing the issue.

The https://docs.nativebase.io/Components.html#floating-label-headref states that when using floatingLabelproperty, it "creates an Input component". It overrides the input I pass in as described by @pipoblak.

As a workaround, I use the exposed MaskService service to handle the masking logic, which enables me to use the masking features of this library. However, it would make sense to let us use custom inputs when using floating labels.

If anyone is interesting, here's a quick example using react hooks (same can be done with class components)

import React, {useState} from 'react';
import {Input, Item, Label, Text, View} from 'native-base';
import {MaskService, TextInputMaskOptionProp} from 'react-native-masked-text';

// generates an object containing the input required properties (value and onChange) and handles state
const useInputState = (initialValue?: string) => {
  const [value, onChange] = useState(initialValue);
  return {value, onChange};
};

// converts the value using the mask parameters
const mask = ({value = '', onChange}, type: string, options?: TextInputMaskOptionProp) => ({
  // the value is converted to a mask so it is displayed properly with the <Input /> component
  value: MaskService.toMask(type, value, options),
  // when the value is modified, it is converted back to its raw value
  onChangeText: newValue => onChange(MaskService.toRawValue(type, newValue, options).join('')),
});

const component = () => {
  const input = useInputState();
  const masked = mask(input, 'credit-card');

  return (
    <View>
      <Item floatingLabel>
        <Label>card number</Label>
        <Input maxLength={19} {...masked} keyboardType='number-pad' />
      </Item>
      <Text>Actual value: {input.value}</Text>
    </View>
  );
};

export default component;

I am also experiencing the issue.

The https://docs.nativebase.io/Components.html#floating-label-headref states that when using floatingLabelproperty, it "creates an Input component". It overrides the input I pass in as described by @pipoblak.

As a workaround, I use the exposed MaskService service to handle the masking logic, which enables me to use the masking features of this library. However, it would make sense to let us use custom inputs when using floating labels.

If anyone is interesting, here's a quick example using react hooks (same can be done with class components)

import React, {useState} from 'react';
import {Input, Item, Label, Text, View} from 'native-base';
import {MaskService, TextInputMaskOptionProp} from 'react-native-masked-text';

// generates an object containing the input required properties (value and onChange) and handles state
const useInputState = (initialValue?: string) => {
  const [value, onChange] = useState(initialValue);
  return {value, onChange};
};

// converts the value using the mask parameters
const mask = ({value = '', onChange}, type: string, options?: TextInputMaskOptionProp) => ({
  // the value is converted to a mask so it is displayed properly with the <Input /> component
  value: MaskService.toMask(type, value, options),
  // when the value is modified, it is converted back to its raw value
  onChangeText: newValue => onChange(MaskService.toRawValue(type, newValue, options).join('')),
});

const component = () => {
  const input = useInputState();
  const masked = mask(input, 'credit-card');

  return (
    <View>
      <Item floatingLabel>
        <Label>card number</Label>
        <Input maxLength={19} {...masked} keyboardType='number-pad' />
      </Item>
      <Text>Actual value: {input.value}</Text>
    </View>
  );
};

export default component;

It works really well. Thanks for sharing.

Im also met this issue, this is really problem

Hi @francescopersico , Feature FloatingLabel for item is limited. You can use solution provided by @robinstraub. Closing this for now.
Thanks.

import React, {useState} from 'react';
import {Input, Item, Label, Text, View} from 'native-base';
import {MaskService, TextInputMaskOptionProp} from 'react-native-masked-text';

// generates an object containing the input required properties (value and onChange) and handles state
const useInputState = (initialValue?: string) => {
  const [value, onChange] = useState(initialValue);
  return {value, onChange};
};

// converts the value using the mask parameters
const mask = ({value = '', onChange}, type: string, options?: TextInputMaskOptionProp) => ({
  // the value is converted to a mask so it is displayed properly with the <Input /> component
  value: MaskService.toMask(type, value, options),
  // when the value is modified, it is converted back to its raw value
  onChangeText: newValue => onChange(MaskService.toRawValue(type, newValue, options).join('')),
});

const component = () => {
  const input = useInputState();
  const masked = mask(input, 'credit-card');

  return (
    <View>
      <Item floatingLabel>
        <Label>card number</Label>
        <Input maxLength={19} {...masked} keyboardType='number-pad' />
      </Item>
      <Text>Actual value: {input.value}</Text>
    </View>
  );
};

export default component;
Was this page helpful?
0 / 5 - 0 ratings