0.1.2 • Published 1 year ago

neos-react-form v0.1.2

Weekly downloads
-
License
MIT
Repository
-
Last release
1 year ago

Neos Flow compatible form components for use with react

Installation

Run

yarn add neos-react-form

Usage

import Form from "../src/components/Form/Form";
import Input from "../src/components/Input/Input";
import Label from "../src/components/Label/Label";
import Select from "../src/components/Select/Select";
import Option from "../src/components/Select/Option";
import Checkbox from "../src/components/Checkbox/Checkbox";
import Textarea from "../src/components/Textarea/Textarea";
import Button from "../src/components/Button/Button";
import FetchFormData from "../src/components/Backend/FetchFormData";

const submitForm = (el) => {
    el.preventDefault();
    const form = el.target;
    FetchFormData('/api/endpoint', 'POST', form).then(result => {
        console.log(result);
    });
}

const change = (el) => {
    console.log('handle change')
    console.log(el)
}

const App = () => {

    // for testing. ... this is your entity object
    const entity = {
        identifier: '123123123',
        text: 'Lorem ipsum dolor amet.',
        select1: 'value 2',
        select2: 'foo 3',
        select3: 'value 3',
        checkbox: '1',
        radio: '',
        textarea: 'Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet.',
    };

    return (
        <div className="App">
            
            <h1>Neos React form</h1>

            <div className="container">

                <Form attributes={{id: 'testForm'}} onSubmit={(p) => submitForm(p)} formData={{foo: entity}} >

                    <div className="mb-3">
                        <Label htmlFor="textInput" attributes={{className: 'form-label'}} >Testlabel</Label>
                        <Input name="foo[text]" attributes={{id: 'textInput', className: 'form-control', placeholder: 'Text input'}} required={true} onChange={(p) => change(p)} />
                    </div>

                    <div className="mb-3">
                        <Label htmlFor="selectBox" attributes={{className: 'form-label'}} >Select box</Label>
                        <Select name="foo[select1]" attributes={{className: 'form-select'}} onChange={(p) => change(p)}
                                options={[
                                    {value: 'value 1', label: 'Label 1'},
                                    {value: 'value 2', label: 'Label 2'},
                                    {value: 'value 3', label: 'Label 3'},
                                ]}
                        />
                    </div>

                    <div className="mb-3">
                        <Label htmlFor="selectBox2" attributes={{className: 'form-label'}} >Select box 2</Label>
                        <Select name="foo[select2]" attributes={{className: 'form-select'}} onChange={(p) => change(p)} >
                            <Option value="foo 1" label="Bar 1" />
                            <Option value="foo 2" label="Bar 2" />
                            <Option value="foo 3" label="Bar 3" />
                        </Select>
                    </div>

                    <div className="mb-3">
                        <Label htmlFor="selectBox3" attributes={{className: 'form-label'}} >Select box 3</Label>
                        <Select name="foo[select3]" attributes={{className: 'form-select'}} onChange={(p) => change(p)}
                                optionLabelField="bar"
                                optionValueField="foo"
                                options={[
                                    {foo: 'value 1', bar: 'Label 1'},
                                    {foo: 'value 2', bar: 'Label 2'},
                                    {foo: 'value 3', bar: 'Label 3'},
                                ]}
                        />
                    </div>

                    <div className="form-check">
                        <Checkbox name="foo[checkbox]" attributes={{id: 'testCheckBox', className: 'form-check-input'}} labelAttributes={{className: 'form-check-label'}} value="1" onChange={(p) => change(p)} >
                            Lorem ipsum dolor amet.
                        </Checkbox>
                    </div>

                    <div className="form-check">
                        <Checkbox name="foo[radio]" type="radio" attributes={{id: 'testRadioButton', className: 'form-check-input'}} labelAttributes={{className: 'form-check-label'}} value="1" onChange={(p) => change(p)} >
                            Lorem ipsum dolor amet.
                        </Checkbox>
                    </div>

                    <div className="mb-3">
                        <Label htmlFor="selectBox3" attributes={{className: 'form-label'}} >Select box 3</Label>
                        <Textarea name="foo[textarea]" attributes={{id: 'textInput', className: 'form-control', placeholder: 'Text input', rows: 8}} onChange={(p) => change(p)} />
                    </div>

                    <div className="mb-3">
                        <Button attributes={{className: 'btn btn-primary'}} >
                            Submit form
                        </Button>
                    </div>
                    
                </Form>
                
            </div>
        </div>
    );
}

Neos Flow action controller example

<?php
namespace Acme\Package\Controller\Api;

/*
 * This file is part of the Acme.Package package.
 */

use Neos\Flow\Annotations as Flow;
use Neos\Flow\Mvc\Controller\ActionController;
use Neos\Flow\Mvc\View\JsonView;
use Acme\Package\Domain\Model\Person;
use Neos\Flow\Property\TypeConverter\PersistentObjectConverter;
use Acme\Package\Domain\Repository\PersonRepository;

#[Flow\Scope("singleton")]
final class PersonController extends ActionController
{
    /**
     * @var string
     */
    protected $defaultViewObjectName = JsonView::class;

    #[Flow\Inject]
    protected PersonRepository $personRepository;

    /** 
     * initializeAction which later belongs in an abstract controller
    */
    protected function initializeAction() {
        $arguments = $this->request->getArguments();
        foreach ($arguments as $argumentIterator => $argument) {
            $propertyMappingConfiguration = $this->arguments[$argumentIterator]->getPropertyMappingConfiguration();
            $propertyMappingConfiguration->setTypeConverterOption(PersistentObjectConverter::class,
                PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED, true );
            $propertyMappingConfiguration->setTypeConverterOption(PersistentObjectConverter::class,
                PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED, true );
            $propertyMappingConfiguration->allowAllProperties()->skipUnknownProperties();
        }
    }

    public function createAction(Person $person): void
    {
        $this->personRepository->add($person);
        $this->view->assign('value', ['response' => 'success', 'result' => $person]);
    }

    public function updateAction(Person $person): void
    {
        $this->personRepository->update($person);
        $this->view->assign('value', ['response' => 'success', 'result' => $person]);
    }

}