Code Monkey home page Code Monkey logo

react-forms's People

Contributors

dovydasnavickas avatar giedriusgrabauskas avatar martynaszilinskas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  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

Forkers

freight-trust

react-forms's Issues

Should Field be renderable outside of Form?

I was implementing proper Field behavior when rendered/removed from FieldsArray (mounting/unmounting, to be precise) and noticed that Field cannot be rendered outside of Form.

But if I'm correct, it's as easy as adding formId prop and updating FormId getter to take that into account, not just context.FormId.

This is what BaseContainer does, inherently BaseFormButton does and Form itself does. Maybe setting formId would enable some scenarios that we didn't yet encounter?

Initialization is a bit off

With the newest update, the validation is being initialized like so:

import { SubscriberContainer } from "simplr-validation/subscribers";
SubscriberContainer.Initialize();

It is a small thing and functionally works well, but it is the first thing that someone wanting to use validation will see and I think it's a bit tricky.

What I propose to do is:
a. Create an initialization method and expose it via main import, like so:

import { InitializeValidation } from "simplr-validation";
InitializeValidation();

Naming is subject to discussion, but the idea of having a function to call in the main import seems to be the best here. Any more ideas on naming or different approach at all?

/cc @GiedriusGrabauskas @MartynasZilinskas

TransitionalValue for fields

In some cases, there might arise necessity to have transitional value:
a value that is not suitable for FormStore yet, but is not invalid either.

Value:
123
Transitional value:
123.

Dot at the end is intentional, because the user might be typing 123.4 and value that is suitable for FormStore is 123, but while the user is typing the end value that one wants, there is a transitional value 123. in between.
We should explore mechanism update for modifiers to have ability to return both values: correct one and a transitional one.

FieldOnChangeCallback update

As the library is not yet released, breaking changes are acceptable.
From early usage outside of package development, I noticed that FieldOnChangeCallback and FormOnSubmitCallback have differences in their parameters.

FieldOnChangeCallback has:

  • event
  • newValue
  • fieldId
  • store

And FormOnSubmitCallback has:

  • event
  • store

While defining and using both callbacks in the same class like so:

onSubmit: FormOnSubmitCallback = (event, store) => {
    // <...>
};

onChange: FieldOnChangeCallback<any> = (event, newValue, fieldId, formId) => {
    // <...>
};

It seems that usage should differ, but in essence, it should not differ that much.

E.g. formId is available in FieldOnChangeCallback, but not in FormOnSubmitCallback. Why so?

Also, store is being passed into FormOnSubmitCallback, but getting FormStore in FieldOnChangeCallback requires importing FSHContainer and getting FormStore with a dance like so:

const store = FSHContainer.FormStoresHandler.GetStore(formId);

Not pretty and could scare an inexperienced user.

Therefore, I suggest updating FieldOnChangeCallback from:

export type FieldOnChangeCallback<TElement> = (
    event: React.FormEvent<TElement>,
    newValue: FieldValue,
    fieldId: string,
    formId: string
) => void;

To:

export type FieldOnChangeCallback<TElement> = (
    event: React.FormEvent<TElement>,
    newValue: FieldValue,
    fieldId: string,
    store: FormStore
) => void;

Changing the last parameter from formId to store.

Also, figuring out which form's store instance you have is a bit tricky at the moment, because FormId property is protected. As TypeScript does not allow us to have different visibility property getter and setter and we cannot make a protected setter and public getter, the solution here is a public GetFormId() method on a FormStore.

Another observation is that public methods like GetFieldId, GetFieldsGroupid and similar ones should be moved out into helpers, because they are cluttering public API.

Validator's message should have a template function overload

Right now constructing error message is a bit limited, because fieldId and fieldName are not available during message construction, unless variable closure is used.

Therefore, error prop in validators could take in a template function:

(fieldName, fieldId): string;

Default validators messages

At the moment, usage of validators is not as smooth as I'd like it to be.
We should add default validator messages.

ErrorsContainer

simplr-validation is already an awesome library. One thing that I struggled while starting using it is showing the errors, which is kind of a main thing for the library.
I think we should create ErrorsContainer or sth for an easy errors rendering.

We discussed a bit in Slack with @MartynasZilinskas, so we'll have something soon.

Chainable/non-chainable modifiers

The concept of modifiers is powerful, but with great power comes great responsibility:
If the modifier is suitable for chaining, it is a bit more complex.

This is why we could have a notion of chainable: boolean on the modifier.

/cc @GiedriusGrabauskas @MartynasZilinskas

Not sure about this one just yet. Let's discuss a bit more.

DOM fields implementation

  • Text
  • Password
  • Email
  • Search
  • Number (Not fully completed see #61)
  • Textarea
  • Checkbox
  • Select

Non default DOM components:

  • RadioGroup
  • Radio
  • Hidden

`Hidden` component causes wrong form `Pristine` value.

If form contains a set of Fields with a prop initialValue and without a prop value and a single Hidden component with all required props defaultValue, initialValue and value, Hidden field causes form Pristine value change to false. You can supply same values for defaultValue, initialValue and value - the outcome is still the same.

Dom Number component issues

We still haven't figured out the proper way of modifier mechanism.
Thus Number field doesn't work as intended. For now, it will be left without modifier which restricts any not numeric or special characters (like minus or comma) usage in the field.

Premade normalizers

Input from users would be really helpful.

  • LowerCase
  • UpperCase
  • Alphanumeric

Implement FormProps.onChange

There are types for FormProps.onChange, but it is not used anywhere yet.

I guess there could be two roads here:

  • A listener for field changes setup on FormStore and a callback called accordingly
  • Every field should proxy it's onChange to the one set on field itself first and the one set on form secondly

First one makes no sense to me as it would comprehend imperative API, which I don't really want to foster. Anyone can subscribe themselves to the store.

Second one adds responsibility for field developers to handle this and proxy the onChange of field into the form one. I guess this TODO describes just that:
https://github.com/SimplrJS/simplr-forms/blob/dev/packages/simplr-forms-dom/src/components/text.tsx#L41

Also, at the moment, FormProps has a property onChange, but I think it's better to call it onFieldChange to explicitly note that this is NOT a change happening on the form itself, but rather a proxied callback from a field.

Unexpected errors

Using versions in package.json:

"@simplr/react-forms": "^4.3.3"
"@simplr/react-forms-dom": "^4.3.3"

Error:

[17:33:55] ERROR TS: D:/Projects/Admin/node_modules/@simplr/react-forms-dom/components/radio-group.d.ts(23,22): error TS2417: Class static side 'typeof RadioGroup' incorrectly extends base class static side 'typeof BaseDomField'.
  Types of property 'childContextTypes' are incompatible.
    Type 'ValidationMap<RadioGroupChildContext>' is not assignable to type 'ValidationMap<FieldChildContext>'.
      Types of property 'FieldId' are incompatible.
        Type 'Validator<RadioGroupChildContext> | undefined' is not assignable to type 'Validator<FieldChildContext> | undefined'.
          Type 'Validator<RadioGroupChildContext>' is not assignable to type 'Validator<FieldChildContext> | undefined'.
            Type 'Validator<RadioGroupChildContext>' is not assignable to type 'Validator<FieldChildContext>'.
              Types of parameters 'object' and 'object' are incompatible.
                Type 'FieldChildContext' is not assignable to type 'RadioGroupChildContext'.
                  Property 'RadioGroupOnChangeHandler' is missing in type 'FieldChildContext'.
[17:33:55] ERROR TS: D:/Projects/Admin/node_modules/@simplr/react-forms-dom/components/radio.d.ts(18,22): error TS2417: Class static side 'typeof Radio' incorrectly extends base class static side 'typeof BaseContainer'.
  Types of property 'contextTypes' are incompatible.
    Type 'ValidationMap<RadioParentContext>' is not assignable to type 'ValidationMap<BaseContainerParentContext>'.
      Types of property 'FormId' are incompatible.
        Type 'Validator<RadioParentContext> | undefined' is not assignable to type 'Validator<BaseContainerParentContext> | undefined'.
          Type 'Validator<RadioParentContext>' is not assignable to type 'Validator<BaseContainerParentContext> | undefined'.
            Type 'Validator<RadioParentContext>' is not assignable to type 'Validator<BaseContainerParentContext>'.
              Types of parameters 'object' and 'object' are incompatible.
                Type 'BaseContainerParentContext' is not assignable to type 'RadioParentContext'.
                  Type 'BaseContainerParentContext' is not assignable to type 'RadioGroupChildContext'.
                    Property 'RadioGroupOnChangeHandler' is missing in type 'BaseContainerParentContext'.

Number input never renders the placeholder

It seems impossible to see the placeholder for the <Number /> input element.

Whenever initialValue/defaultValue props are passed 0, null, undefined or even "" values the value="0" HTML attribute is always rendered.

The only solution for displaying the placeholder is passing value="" prop, but obviously the prop doesn't use the built-in onChange handling then and becomes non-editable.

<Number
  name="somename"
  placeholder={"Test placeholder"}
/>

Public API cleanup

As mentioned in #75, public API should not expose some methods that are not going to be used that often.
They should be moved into helpers.

FieldsGroup implementation

  • FieldsGroup base
  • FormStore implementation
  • FieldsGroup implementation in field
  • Identical FieldsGroups grouping to array in formStore.ToObject()

Premade Validators implementation

  • Required
  • Exclusion - check if value isn't in exclusion list

Number validators

  • OddNumber
  • EvenNumber
  • GreaterThanNumber
  • GreaterThanOrEqualToNumber
  • EqualToNumber
  • LessThanNumber
  • LessThanOrEqualToNumber

Implementation of NPM package Validator:

  • Contains
  • Equals
  • Alpha
  • Alphanumeric
  • Ascii
  • Base64
  • Boolean
  • ByteLength
  • CreditCard
  • Currency
  • DataURI - check if the string is a data uri format
  • Decimal - check if the string is decimal
  • DivisibleBy - check if the string is a number that's divisible by another
  • Email
  • EmptyString
  • FQDN - check if the string is a fully qualified domain name (e.g. domain.com)
  • Float - check if the string is a float.
  • FullWidth - check if the string contains any full-width chars.
  • HalfWidth - check if the string contains any half-width chars.
  • HexColor
  • Hexadecimal
  • IP - check if the string is an IP (version 4 or 6).
  • ISBN - check if the string is an ISBN (version 10 or 13).
  • ISSN - check if the string is an ISSN.
  • ISIN - check if the string is an ISIN
  • ISO8601 - check if the string is a valid ISO 8601 date
  • Inclusion - check if the string is in a array of allowed values
  • Int
  • JSON - check if the string is valid JSON (note: uses JSON.parse)
  • Length - check if the string's length falls in a range
  • Lowercase
  • MACAdress
  • MD5
  • MobilePhone
    Mongold
  • Multibyte
  • Numeric
  • SurrogatePair
  • URL
  • UUID
  • Uppercase
  • VariableWidth
  • Whitelisted - checks characters if they appear in the whitelist.
  • Matches (Regex)

Other:

  • DebounceValidator

Check type after value normalization

For a dev build of forms, there should be a type check after each value normalization.
If value type changes, an error should be thrown to use modifier for that.

Premade modifiers

Input from users would be really helpful.

  • StringToDecimalModifier
  • StringToTagsModifier
  • ApplyToArrayModifier

Validation onBlur

Quite a common scenario that people are almost used to is validation on blur, i.e. when the field looses focus. We should be able to implement this quite easily, shouldn't we?

/cc @MartynasZilinskas

Form builder from object

Very convenient way of using the forms would be to have a builder constructing a form for a given object.
It would not be a declarative way of doing things, but I imagine it being more of a code-generation tool, than automagical builder, even though it would be used by many, I assume, it would have quite a few challenges by itself.

Just an idea for now, so no commitment.

Form onLoad event

In order to get FormStore outside of form events (onChange, onSubmit, etc.), developer has to pass a custom formId into Form and use the same id to get FormStore later on:

componentDidMount() {
    const store = FSHContainer.FormStoresHandler.GetStore("form");
}

<Form formId="form">
    {/* Fields go here */}
</Form>

To get the form store in a more convenient manner, it would be great to have onLoad event on Form where an instance of FormStore would be passed.

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.