TransWikia.com

Pegar os dados de um formulário dinâmico e passar para um estado do tipo array

Stack Overflow em Português Asked by mahilson Hagner on December 19, 2021

Estou tentando pegar os dados de inputs dinâmicos e passar passar para os estado (handleChange), porém não consigo, pois está pegando os valores digitados somente no primeiro input e quando digito nos demais, dá um erro.

Como posso fazer para passar o valor dos inputs dinâmicos para o estado?

Já tentei declarar o estado da seguinte forma abaixo, porém não deu certo:

this.state = { participantes: [{}], }

this.state = { participantes: [{nome: []}], }

no change tentei passar o seguinte código:

handleParticipanteNomeChange = (value, index) => { 
    let dados = this.state.participantes 
    dados[index].nome = value 
    this.setState({ participantes: dados }) 
}

Segue o pedaço do código com a declaração do estado, change e inputs dinâmicos (código no github)

this.state = {
        nome: undefined,
        descricao: undefined,
        dataCriacao: undefined,
        diaRecebimento: undefined,
        diaPagamento: undefined,
        mesAnoInicio: undefined,
        mesAnoFim: undefined,
        valorMensal: undefined,
        jurosMensal: undefined,
        jurosAcumulativo: false,
        participantes: [{}],
        loading: false,
        tableLoading: false,
        grupos: [],
        visible: false,
        current: 0,
        edicao: false,
        array: []
    }

    this.limpaCampos = this.limpaCampos.bind(this)
    this.handleSubmit = this.handleSubmit.bind(this)
    this.editarGrupo = this.editarGrupo.bind(this)
}

listarGrupos() {
    this.setState({ tableLoading: true })
    api.get('/grupos')
        .then(response => this.setState({ grupos: response.data }))
        .then(response => this.setState({ tableLoading: false }))
        .catch(error => {
            console.log(error)
        })
}

handleSubmit = (e) => {
    e.preventDefault()

    this.setState({
        mesAnoInicio: moment(moment(this.state.mesAnoInicio).format("L"), "MMDDYYYY").format(),
        mesAnoFim: moment(moment(this.state.mesAnoFim).format("L"), "MMDDYYYY").format()
    })

    const { nome, descricao, diaPagamento, diaRecebimento, mesAnoInicio, mesAnoFim,
        valorMensal, jurosAcumulativo, jurosMensal, participantes } = this.state

    this.setState({ loading: true })

    api.post(`/grupos`, {
        nome, descricao, diaPagamento, diaRecebimento, mesAnoInicio,
        mesAnoFim, valorMensal, jurosAcumulativo, jurosMensal, participantes
    })
        .then(response => [
            this.setState({ loading: false }),
            this.limpaCampos(),
            this.setState({
                visible: false
            }),
            this.listarGrupos()
        ])
        .catch(e => [
            this.setState({ loading: false }),
            notification.error({
                message: 'Ops!',
                description: e.response.data.message.toString()
            })
        ])

}

deletarGrupo = (grupo) => {
    this.setState({ tableLoading: true })
    api.delete(`/grupos/${grupo._id}`)
        .then(response => [
            notification.success({
                message: 'Sucesso!',
                description:
                    response.data.message.toString()
            })
        ])
        .then(response => this.setState({ tableLoading: false }))
        .then(response => this.listarGrupos())
        .catch(e => [
            this.setState({ loading: false }),
            notification.error({
                message: 'Ops!',
                description: e.response.data.message.toString()
            })
        ])
}

editarGrupo = (grupo) => {
    api.put(`/grupos/${grupo._id}`)
        .then(response => [
            notification.success({
                message: 'Sucesso!',
                description:
                    response.data.message.toString()
            })
        ])
        .then(response => this.listarGrupos())
        .catch(e => [
            this.setState({ loading: false }),
            notification.error({
                message: 'Ops!',
                description: e.response.data.message.toString()
            })
        ])

}

limpaCampos() {
    this.setState({
        nome: '',
        edicao: false,
        grupos: [],
        descricao: '',
        diaPagamento: '',
        diaRecebimento: '',
        current: 0,
        mesAnoInicio: undefined,
        mesAnoFim: undefined,
        valorMensal: undefined,
        jurosMensal: undefined,
        participantes: [
            { nome: [] }
        ],
        array: []
    })
    this.listarGrupos()

}

showModal = () => {
    this.setState({
        visible: true,
    });
};


handleEdit = (id) => {
    const grupos = this.state.grupos.filter((grupo) => {
        return grupo._id === id
    })

    const firtItem = grupos[0]
    let parts = []
    parts = firtItem.participantes

    let partsNome = parts.map(p => (p.nome))

    this.setState({
        ...this.state,
        nome: firtItem.nome,
        descricao: firtItem.descricao,
        diaPagamento: firtItem.diaPagamento,
        diaRecebimento: firtItem.diaRecebimento,
        mesAnoInicio: firtItem.mesAnoInicio,
        mesAnoFim: firtItem.mesAnoFim,
        valorMensal: firtItem.valorMensal,
        jurosAcumulativo: firtItem.jurosAcumulativo,
        jurosMensal: firtItem.jurosMensal,
        edicao: true,
        participantes: [
            { nome: partsNome }
        ]
    })

    this.setState({ array: this.state.grupos[0].participantes })

    this.showModal()
}

handleCancel = () => {
    this.setState({
        visible: false
    });
    this.limpaCampos()
};

handleChange = (e) => {
    this.setState({
        [e.target.name]: e.target.value
    })
}

handleDiaRecebimentoChange = value => {
    this.setState({
        diaRecebimento: value
    });
};

handleDiaPagamentoChange = value => {
    this.setState({
        diaPagamento: value
    });
};

handleJurosMesalChange = (value) => {
    this.setState({
        jurosMensal: value
    });
};

handleValorMensalChange = (value) => {
    this.setState({
        valorMensal: value
    })
}

handleDataInicioChange = (value) => {
    this.setState({
        mesAnoInicio: value
    });
};

handleDataFimChange = (value) => {
    this.setState({
        mesAnoFim: value
    });
};

handleChecked = (checked) => {
    this.setState({ jurosAcumulativo: checked })

    return (this.state.jurosAcumulativo) ?
        this.setState({ jurosMensal: undefined }) : null
}

componentDidMount() {
    this.listarGrupos()
}

next() {
    const current = this.state.current + 1
    this.setState({ current })
}

prev() {
    const current = this.state.current - 1
    this.setState({ current })
}

calculaQuantidadeDeMeses = () => {
    var inicio = moment(this.state.mesAnoInicio)
    var fim = moment(this.state.mesAnoFim)
    var qtdeMeses = (fim.diff(inicio, 'months') + 1)
    return qtdeMeses + 1
}

remove = (k) => {
    const { form } = this.props;
    // can use data-binding to get
    const keys = form.getFieldValue('keys');
    // We need at least one passenger
    if (keys.length === 1) {
        return;
    }
    // can use data-binding to set
    form.setFieldsValue({
        keys: keys.filter(key => key !== k),
    });
}

add = () => {

    uuid++;
    const { form } = this.props;
    // can use data-binding to get
    const keys = form.getFieldValue('keys');

    var meses = this.calculaQuantidadeDeMeses()

    if (keys.length < meses) {
        const nextKeys = keys.concat(uuid);
        // can use data-binding to set
        // important! notify form to detect changes

        form.setFieldsValue({
            keys: nextKeys,
        });
    } else return;
}

handleParticipanteNomeChange = (value, index) => {
    let dados = this.state.participantes
    dados[index].nome = value
    this.setState({ participantes: dados[index].nome })
    console.log(this.state.participantes)
}

atualizaStadoDoArray = (array) => {
    this.setState({ participantes: array })
}

render() {
    const formItemLayout = {    
        labelCol: { span: 6 },
        wrapperCol: { span: 14 },
    };
    const { getFieldDecorator, getFieldValue } = this.props.form;
    const { TextArea } = Input;
    const { visible, loading, current, grupos, edicao } = this.state;


    getFieldDecorator('keys', { initialValue: (edicao) ? this.state.array : [] });

    const keys = getFieldValue('keys');


    const formItems = keys.map((item, index) => {

        const part = 'participantes'

        getFieldDecorator(`${item}[${index}].nome`, {
            initialValue: item.nome
        })

        const { participantes } = this.state

        return (
            <Row gutter={24}>
                <Col span={16}>
                    <FormItem
                        required={false}
                        key={index}
                    >
                        {getFieldDecorator(`${item}[${index}].nome`)(
                            <Input
                                name={`${part}[${index}][nome]`}
                                placeholder="Digite o nome"
                                style={{ width: '100%', marginRight: 10 }}
                                onChange={(e) => this.handleParticipanteNomeChange(e.target.value, index)}
                            />
                        )}
                    </FormItem>
                </Col>
                <Col span={2}>
                    <If test={keys.length > 1}>
                        <Icon
                            className="dynamic-delete-button"
                            type="minus-circle-o"
                            disabled={keys.length === 1}
                            onClick={() => this.remove(item)}
                        />
                    </If>
                </Col>
            </Row>
        );
    });

    return (
        <div>
            <Tamplate>
                <Button
                    type="primary"
                    onClick={this.showModal}
                    style={{ marginBottom: 20 }}>
                    <Icon type="usergroup-add" style={{ fontSize: '18px' }} />
                    Novo Grupo
                </Button>

                <Modal
                    className='modal'
                    style={{ marginBottom: 24 }}
                    visible={visible}
                    title='Cadastrar novo Grupo'
                    onCancel={this.handleCancel}
                    wrapClassName="vertical-center-modal"
                    footer={
                        [
                            <Button
                                //key="submit"
                                type="default"
                                onClick={this.handleCancel}>
                                Cancelar
                            </Button>,
                            <If test={(steps[this.state.current].content) === 'Participantes-content'} >
                                <Button
                                    key="edit"
                                    type="primary"
                                    loading={loading}
                                    onClick={this.handleSubmit}>
                                    Salvar
                                </Button>
                            </If>
                        ]}
                >
                    <div style={{ background: '#fff', padding: 20, minHeight: 280 }}>
                        <Form onSubmit={this.handleSubmit} layout='vertical' >

                            <Steps current={current} style={{ marginBottom: 20 }}>
                                {steps.map(item => <Step key={item.title} title={item.title} />)}
                            </Steps>

                            <div style={{ background: '#fff', padding: 20, minHeight: 280 }}>
                                <If test={(steps[this.state.current].content) === 'Grupo-content'} >
                                    <Form.Item label="Nome do grupo">
                                        <Input
                                            name='nome'
                                            onChange={this.handleChange.bind(this)}
                                            value={this.state.nome}
                                        />
                                    </Form.Item>
                                    <Form.Item label="Descrição do grupo">
                                        <TextArea
                                            placeholder="Informe uma descrição sobre esse grupo"
                                            name='descricao'
                                            onChange={this.handleChange.bind(this)}
                                            autosize={{ minRows: 2, maxRows: 6 }}
                                            required={true}
                                            value={this.state.descricao}
                                        />
                                    </Form.Item>
                                    <Row gutter={24}>
                                        <Col span={10}>
                                            <Form.Item label="Dia de pagamento">
                                                <InputNumber
                                                    min={5}
                                                    max={8}
                                                    name='diaPagamento'
                                                    value={this.state.diaPagamento}
                                                    onChange={this.handleDiaPagamentoChange}
                                                />
                                            </Form.Item>
                                        </Col>
                                        <Col span={10}>
                                            <Form.Item label="Dia de recebimento">
                                                <InputNumber
                                                    min={10}
                                                    max={15}
                                                    name='diaPagamento'
                                                    value={this.state.diaRecebimento}
                                                    onChange={this.handleDiaRecebimentoChange}
                                                />
                                            </Form.Item>
                                        </Col>
                                    </Row>

                                    <Row gutter={24}>
                                        <Col span={10}>
                                            <Form.Item label="Mês/Ano Início">
                                                <MonthPicker
                                                    name='mesAnoInicio'
                                                    placeholder='Selecione a data'
                                                    format={mesFormat}
                                                    value={moment(this.state.mesAnoInicio)}
                                                    onChange={this.handleDataInicioChange}
                                                />
                                            </Form.Item>
                                        </Col>
                                        <Col span={10}>
                                            <Form.Item label="Mês/Ano Fim">
                                                <MonthPicker
                                                    name='mesAnoFim'
                                                    placeholder='Selecione a data'
                                                    format={mesFormat}
                                                    value={moment(this.state.mesAnoFim)}
                                                    onChange={this.handleDataFimChange}
                                                />
                                            </Form.Item>
                                        </Col>
                                    </Row>
                                </If>
                                <If test={(steps[this.state.current].content) === 'Valores-content'} >
                                    <Row gutter={24}>
                                        <Col span={10}>
                                            <Form.Item label="Mensalidade - R$">
                                                <Input
                                                    name="valorMensal"
                                                    type="text"
                                                    value={this.state.valorMensal}
                                                    onChange={(e) => this.handleValorMensalChange(e.target.value)}
                                                />
                                            </Form.Item>
                                        </Col>
                                    </Row>
                                    <Row gutter={24}>
                                        <Col span={10}>
                                            <Form.Item label="Juros acumulativo mensal?">
                                                <Switch
                                                    onChange={this.handleChecked}
                                                    defaultChecked={this.state.jurosAcumulativo}
                                                />
                                            </Form.Item>
                                        </Col>
                                    </Row>
                                    <Row gutter={24}>
                                        <Col span={10}>
                                            <If test={this.state.jurosAcumulativo}>
                                                <Form.Item label="% percentual de juros/mês">
                                                    <InputNumber
                                                        min={2}
                                                        max={6}
                                                        name='jurosMensal'
                                                        formatter={value => `${value}%`}
                                                        value={this.state.jurosMensal}
                                                        onChange={this.handleJurosMesalChange}
                                                    />
                                                </Form.Item>
                                            </If>
                                        </Col>
                                    </Row>
                                </If>
                                <If test={(steps[this.state.current].content) === 'Participantes-content'} >
                                    <p>Quantidade de participantes possíveis: {this.calculaQuantidadeDeMeses()}</p>
                                    {formItems}
                                    <FormItem>
                                        <Button
                                            type="dashed"
                                            onClick={this.add}
                                            style={{ width: '60%' }}>
                                            <Icon type="plus" />
                                            Adicionar participante
                                        </Button>
                                    </FormItem>
                                </If>
                            </div>
                            <div className="steps-action">
                                <ButtonGroup>
                                    <Button
                                        type="primary"
                                        style={{ marginLeft: 8 }}
                                        onClick={() => this.prev()}
                                        disabled={this.state.current <= 0}
                                    >
                                        <Icon type="left" />
                                        Voltar
                                    </Button>
                                    <Button
                                        type="primary"
                                        onClick={() => this.next()}
                                        disabled={this.state.current >= 2}
                                    >
                                        Próximo
                                        <Icon type="right" />
                                    </Button>
                                </ButtonGroup>
                            </div>
                        </Form>
                    </div>
                </Modal>
                <Spin
                    tip='Carregando...'
                    spinning={this.state.tableLoading}
                >
                    <Table
                        pagination={{
                            pageSizeOptions: ['30', '50'],
                            showSizeChanger: true
                        }}
                        dados={this.state.grupos}
                        deletarGrupo={this.deletarGrupo}
                        handleEdit={(id) => this.handleEdit(id)}
                    />
                </Spin>
            </Tamplate>
        </div >
    )

Erro gerado:

TypeError: Cannot create property 'nome' on string 'm'
Grupo.handleParticipanteNomeChange
C:/Users/Administrador/Documents/Meus Projetos/admgoiafio/src/pages/grupo.js:349
346 |
347 | handleParticipanteNomeChange = (value, index) => {
348 | let dados = this.state.participantes
349 | dados[index].nome = value
| ^ 350 | this.setState({ participantes: dados[index].nome })
351 | console.log(this.state.participantes)
352 | }
View compiled
onChange
C:/Users/Administrador/Documents/Meus Projetos/admgoiafio/src/pages/grupo.js:395
392 | name={
${part}[${index}][nome]}
393 | placeholder="Digite o nome"
394 | style={{ width: '100%', marginRight: 10 }}
395 | onChange={(e) => this.handleParticipanteNomeChange(e.target.value, index)}
| ^ 396 | />
397 | )}
398 | </FormItem>

View compiled

Uncaught TypeError: Cannot create property 'nome' on string 'm'
at Grupo.handleParticipanteNomeChange (grupo.js:349)
at Object.onChange (grupo.js:395)
at Object.onCollectCommon (createBaseForm.js:85)
at Object.onCollect (createBaseForm.js:115)
at Input.setValue (Input.js:247)
at Input._this.handleChange (Input.js:178)
at HTMLUnknownElement.callCallback (react-dom.development.js:147)
at Object.invokeGuardedCallbackDev (react-dom.development.js:196)
at invokeGuardedCallback (react-dom.development.js:250)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:265)
at executeDispatch (react-dom.development.js:571)
at executeDispatchesInOrder (react-dom.development.js:596)
at executeDispatchesAndRelease (react-dom.development.js:695)
at executeDispatchesAndReleaseTopLevel (react-dom.development.js:704)
at Array.forEach (<anonymous>)
at forEachAccumulated (react-dom.development.js:674)
at runEventsInBatch (react-dom.development.js:844)
at runExtractedEventsInBatch (react-dom.development.js:852)
at handleTopLevel (react-dom.development.js:5030)
at batchedUpdates$1 (react-dom.development.js:21469)
at batchedUpdates (react-dom.development.js:2247)
at dispatchEvent (react-dom.development.js:5110)
at react-dom.development.js:21526
at Object.unstable_runWithPriority (scheduler.development.js:255)
at interactiveUpdates$1 (react-dom.development.js:21525)
at interactiveUpdates (react-dom.development.js:2268)
at dispatchInteractiveEvent (react-dom.development.js:50

2 Answers

Voce pode tentar fazer uma função com document.querySelectorAll('input'); depois faz um map pelo array de inputs extraindo o valor para um novo array.

Answered by Rafael Mendes on December 19, 2021

Boa tarde Virgilio,

Ok atendi, porém meu formulário e dinâmico ou seja, posso adicionar mais imputs dinamicamente ao meu form e tenho que enviar esses vários nomes de participantes para o estado, nesse caso para um array. Eu estou até conseguindo enviar o nome do primeiro participante para o estado, porém a partir do segundo dá o erro.

Para exemplicar melhor, segue um print do meu form:

inserir a descrição da imagem aqui

Answered by mahilson Hagner on December 19, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP