Giter VIP home page Giter VIP logo

fusion-form's Introduction

Fusion Form

Pure fusion form rendering with afx support!

Documentation

Neos.Fusion.Form - Form Rendering and Data Binding

This part covers the rendering of forms that are bound to objects or data and will be submitted to a custom Controller Action.

Form.Fusion.Form:Runtime - Runtime Single/Multistep Forms with Actions

This part covers the definition of forms with validation and finishing actions via Fusion. Use cases like contact forms and newsletter subscriptions should be implemented like this.

Development targets

  • Form rendering in fusion with afx and data binding
  • Clear separation of automation and magic for understandable results
  • Flexibility:
    • Make no assumption about the required markup like classNames
    • Allow to override all automatically assigned attributes
    • Enable form fragments as fusion components
    • Allow to bind multiple objects to a single form
    • Enable to create custom controls with
    • Respect form elements that are defined as plain html when rendering __trustedProperties
  • Convenience:
    • Render hidden fields for validation, security and persistence magic
    • Provide validation-errors and restore previously submitted values
    • Prefix fieldnames with the current request namespace if needed
  • Make writing of fusion backend modules easy:
    • Create a backend field container with translated labels and error messages
    • Adjust field markup inside the field container for the neos-backend

Important Deviations from Fluid Form ViewHelpers

The following deviations are probably the ones fluid developers will stumble over. There are many more deviations but those are breaking concept changes you should be aware of.

  • Instead of binding a single object a data DataStructure is bound to the form.
  • Form data-binding is defined via form.data.object={object} instead of objectName and object.
  • Field data-binding is defined vis field.name="object[title]" with the object name and square brackets for nesting.
  • Data binding with property path syntax is not supported.
  • Select options and groups are defined directly as afx content and not options.

Important deviations from the concepts of the Neos.Form package

  • The definitions for form rendering and validation are separated into content and schema of the process.
  • By default the SingleStepProcess is used as this is the most common case. If you need multiple steps the process has to be altered to MultiStepProcess
  • Settings, form data and node properties can be used in a unified way via Fusion to define actions and control the process.
  • Confirmations are no special feature but can be defined as "step" in a MultiStepProcess
  • The concept of finishers is replaced with actions.
  • Actions cannot decide to send the user back into the form process.

fusion-form's People

Contributors

beromir avatar bwaidelich avatar cvette avatar daniellienert avatar faso-dev avatar freesh avatar grebaldi avatar jonnitto avatar kdambekalns avatar koehnlein avatar manumaticx avatar markusguenther avatar martinhauke avatar mficzel avatar mhsdesign avatar simonschaufi avatar skurfuerst avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

fusion-form's Issues

Make state initialization process more flexible

Recently we had several request for manipulating form state initialization like:

  • Initialize the state from some third party tool like SAP or marketing automation
  • Restore the form state after mail verification without persisting the complete state in the state hash
  • Restore the form state after returning from some third party authentication process

props.class ignored in FieldContainer

In Neos.Fusion.Form:FieldContainer the class property is ignored and the error class is always rendered.

In my opinion the condition for the error class should be in braces. That worked for me.

PR: #54

Discuss logic in "Radio.fusion"

// HINT: the "value" argument (4) is null here, because "field.value" should only be filled with the CHOSEN value;
    //       in these two cases:
    //       - when an object is bound to the form, and "property" is defined
    //       - when the form is re-shown in case of a validation error.
    // We use field.value to determine if we should check the value.
    @context.field = ${Form.createFieldDefinition(this.form, this.name, this.property, null)}

Handle empty hidden values again.

For some form fields like checkboxes an empty value is needed to ensure that null values get actually submitted. Those empty values should be created in the form rendering by parsing the content similar to what is done for trusted properties.

Check generation of trusted properties token

Currently the token uses a very simple xpath selector to find all names. We will probably have to tweak this and check wether the empty "[]" at the end of multivalues are already properly supported.

Object to String casting breaks rendering

When using Select with Options the rendering can break in some cases when passing domain models (or other objects) to the option value. This is because of the following code in prototype(Neos.Fusion.Form:Select.Option):

        renderer = afx`
           <option
               value={option.getTargetValueStringified()}
               selected={props.selected}
               {...props.attributes}
           >
               {props.content || option.getTargetValue()}
           </option>
        `

this should be changed to:

...
{props.content || option.getTargetValueStringified()}
...

Field model: New property "name without namespace"

The getName() method of the Field domain model always returns the field name with its namespace.

Would you be open to add a getter "get name without namespace" (how should we name it)?

My use case:

To add frontend validation for my form, I need to evaluate the Schema definition of a field. So I want to check if field foo is configured in the SchemaDefinition. Since the schema definition uses the field name without namespace, I cannot look it up without such a getter.

"Empty" forms lack entity identifier when submitted

When using a form like this for calling a delete action (deleteAction(Company $company)), the required argument is missing, even though props.company contains the correct entity:

<Neos.Fusion.Form:Form form.data.company={props.company} form.target.action={"delete"}>
    <button type="submit" class="neos-button neos-button-danger" title="Eintrag löschen">
        Ja, diesen Eintrag löschen
    </button>
</Neos.Fusion.Form:Form>

When "using" something from the entity like below, it works:

<Neos.Fusion.Form:Form form.data.company={props.company} form.target.action={"delete"}>
    <!-- Necessary to enable the delete method, without this hidden field the identity were -->                           
    <Neos.Fusion.Form:Neos.BackendModule.FieldContainer field.name="company[description]" label="">
        <Neos.Fusion.Form:Hidden/>
    </Neos.Fusion.Form:Neos.BackendModule.FieldContainer>

    <button type="submit" class="neos-button neos-button-danger" title="Eintrag löschen">
        Ja, diesen Eintrag löschen
    </button>
</Neos.Fusion.Form:Form>

Feels wrong to me…

Allow to specify the action/target of runtime forms

While not necessary making the target of a runtime form configurable would allow:

  1. To scroll to an anchor after submitting for following steps or confirmation messages.
  2. To render the first part of a form process on a different page but proceed on another one.

Discuss: FieldContainer vs FieldComponent

FieldContainer:

  • Instantiate field context
  • Render Label and Error
  • Take Fields as Content

FieldComponent:

  • Instantiate field context or reuse FieldContext from container
  • Base for implement controls

Questions:

  • Do we have better names for this

Preset form values (from bound object) are not used if you submit another form

Szenario:
Have two different forms on one page. Bind the forms to an object so that the fields are filled form properties of that object.
If you now submit one of the forms and you have validation errors the values in the not submitted form are cleared.

The Method field.findCurrentValueByPath() returns NULL for every form field of the unsubmitted form.
Thats because $this->form->getResult()->hasErrors() is true for both forms and not just for the form that got submitted.

Expected Behaviour:
All form fields of the form that has not been touched should still display the properties of the bound object.

Export documentation?

Just wanted to look up something in a local install and noticed the documentation is missing, due to the .gitignore config. Any particular reason to not include it? This way the readme is there but points to missing files which is a bit unfortunate :D

Fusion.Form-Runtime

There should be a pure fusion way to define forms and connect them with the data handling code.

  • support 100 % custom rendering
  • separate data model and rendering
  • can be defined via fusion (and in future via nodes)
  • allow reuse of definitions via fusion prototypes
  • allows to easily implement handling actions

Add missing field types

Some FieldTypes like Checkbox, Password, Hidden are not yet implemented.
Maybe we also want a generic Neos.Fusion.Form:Input fieldType that allows to define the type via prop.

Test handling of parent request

The implementation suggests to use the parent request like this:

<Neos.Fusion:Form
        form.object={example}
        form.name="example"
        form.request={request.parentRequest}
        method="post"
    >

we have to check wether this really suits the use cases for the feature

Verify Handling of Object Identities

The handling of Flow Entities as identifier strings has to be checked. Probably this will not work yet.
At the current point we assume that no additional and hidden identity fields are needed.

Add support for multiple file upload field

With the following form configuration in place the submitted data values contain only the first selected file of the multiple file upload field attachments.

I have discovered that the underlying issue is how the __trustedProperties field value is created.

Form configuration

prototype(My.Package:Content.ApplicationForm) < prototype(Neos.Neos:ContentComponent) {
    renderer = Neos.Fusion.Form:Runtime.RuntimeForm {
            namespace = 'application_form'
    
            process {
                content = My.Package:Components.ApplicationForm

                schema = Neos.Fusion.Form:Runtime.SchemaCollection {
                    name = ${Form.Schema.string().isRequired()}
                    email = ${Form.Schema.string().isRequired().validator('EmailAddress')}
                    attachments = ${Form.Schema.arrayOf(Form.Schema.resource().isRequired().validator('Neos\Fusion\Form\Runtime\Validation\Validator\FileTypeValidator', { allowedMediaTypes: ['image/jpeg', 'application/pdf'] }))}
                    picture = ${Form.Schema.resource().isRequired().validator('Neos\Fusion\Form\Runtime\Validation\Validator\FileTypeValidator', { allowedMediaTypes: ['image/jpeg'] })}
                }
            }

            action {
                email {
                    type = 'Neos.Fusion.Form.Runtime:Email'
                    options {
                        senderAddress = ...
                        senderName = ${data.name}
                        replyToAddress = ${data.email}
                        recipientAddress = ...
                        subject = "..."
                        attachments {
                             multipleFileUpload = ${data.attachments}
                             singleFileUpload = ${data.picture}
                        }
                        text = "..."
                    }
                }
            }
        }
}

prototype(My.Package:Components.ApplicationForm) < prototype(Neos.Fusion:Component) {
    renderer = afx`
        <fieldset>
            <legend>Application form</legend>
        </fieldset>

        <Neos.Fusion.Form:FieldContainer field.name="name" label="Name">
            <Neos.Fusion.Form:Input>
        </Neos.Fusion.Form:FieldContainer>

        <Neos.Fusion.Form:FieldContainer field.name="email" label="Email">
            <Neos.Fusion.Form:Input 
                attributes.type="email" 
            />
        </Neos.Fusion.Form:FieldContainer>

        <!-- multiple file upload-->
        <Neos.Fusion.Form:FieldContainer field.name="attachments" label="Attachments">
            <input 
                name={field.getName() + '[]'} 
                type="file"
                multiple={true} 
            />
        </Neos.Fusion.Form:FieldContainer>

        <!-- single file upload-->
        <Neos.Fusion.Form:FieldContainer field.name="picture" label="Attachments">
            <Neos.Fusion.Form:Upload />
        </Neos.Fusion.Form:FieldContainer>
    `
}

FormHelper: incorrect FieldDefinition-constructor argument

Hey guys,
in Class: Neos.Fusion.Form/Classes/Eel/FormHelper.php the FieldDefinition constructor gets called with $multiple as NULL, but the corresponding getter only returns boolean.

FormHelper Line ~84:

if (!$name) {
    /**  new FieldDefinition(string $name = null, $value = null, $multiple = false, ...) **/
    return new FieldDefinition(null, null, null);
}

*FieldDefinition Line: ~71:

/**
 * @return bool
 */
public function isMultiple(): bool
{
    return $this->multiple;
}

BUG: `data` get's lost when processed thru `Neos.Fusion.Form:Runtime.RuntimeForm` outside Form content

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

When data properties are used inside header or footer part of the form, the Neos.Fusion.Form:Runtime.RuntimeForm strips it's values when form is validated / processed.

Expected Behavior

The data should be keept intact if for instance the form has a custom footer button and code which should persist a form validation / reload.

Steps To Reproduce

  1. create a form inside Neos.Fusion.Form:Runtime.RuntimeForm
  2. add some non empty field validation
  3. overwrite its footer content with defined data properties like custom submit button
  4. submit empty form on the front end with validation
  5. on processing the data properties are lost

Environment

- Flow: 8.3 
- Neos: 8.3
- PHP: 8.1

Anything else?

All data properties passed inside the form content withstand the issue and are working properly.

Handle Multivalues for Checkboxes and Selects

The MultiValues for Checkboxes and Selects have to be implemented. Currently this is only done for a MultiSelectBox.

It is possible that a MultiFieldDefinition is needed which would allow us to add strict types to the form definition getValue again.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.