Skip to content

Rewrite form and form control API #1765

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 6, 2016
Merged

Rewrite form and form control API #1765

merged 2 commits into from
Apr 6, 2016

Conversation

taion
Copy link
Member

@taion taion commented Apr 1, 2016

No description provided.

return (
<label className={classNames(className, classes)} style={style}>
<input {...props} type="radio" disabled={disabled} />
{' '}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whats with the extra &nbsp ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't realize it was unneeded here. Will remove, thanks.

@taion taion force-pushed the inputs branch 5 times, most recently from 2e6d4a2 to 6ef38a5 Compare April 2, 2016 19:30
@taion
Copy link
Member Author

taion commented Apr 2, 2016

This looks a bit awkward:

<Form componentClass="fieldset" inline>

If this bothers me enough, I might add e.g. <FieldSet inline> or something.

This is mostly feature-complete now on the API side. I don't have support for .input-sm or .input-lg, but that can be replicated with bsSize on <FormGroup> or <InputGroup>.

Only real missing thing is validation state support on <Checkbox> and <Radio>.

Thoughts? I think the API is clearer, but in more complex cases (e.g. the horizontal form with input group and validation), it's a lot more verbose.

@jquense
Copy link
Member

jquense commented Apr 3, 2016

I'll take a look at the validation stuff, but in the past I haven't used it at all since it's annoying to have the class on the form-group vs the input... tbh I haven't found a good way to handle it with react-formal aside from custom Form-group component... never used the icon stuff tho

case 'success': return 'ok';
case 'warning': return 'warning-sign';
case 'error': return 'remove';
default: return null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the icons used are just "suggested" or examples, I don't think there is any reason why they need to be these three. perhaps this.props.glyph should be used used if it exists?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think that's necessary if we already have support for doing a fully custom feedback thing? Like

<FormControl.Feedback>
  <Glyphicon glyph="music" />
</FormControl.Feedback>

from the examples?

I feel like I don't want to have two APIs for custom feedback icons, and it seems like it'd be better to only have the more general one.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aww yeah that's fine, sorry I missed the code branch for when there are children.

@taion taion force-pushed the inputs branch 4 times, most recently from 6d64a82 to e589d1b Compare April 5, 2016 05:54
@taion taion changed the title [wip] Form refactor Rewrite form and form control API Apr 5, 2016
@taion
Copy link
Member Author

taion commented Apr 5, 2016

This is ready to go now.

I also broke ValidComponentChildren, but only a little, and only to bring it more in line with React.Children and Array.prototype (numberOf -> count, findValidComponents -> filter).

const {
componentClass: Component,
type,
id = this.getControlId(this.context.$bs_formGroup),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if controlID exists does it makes more sense to use it over the specified props.id so that there isn't a potential label with an htmlFor pointing to nothing by mistake?

Or maybe just warn?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A warning makes sense to me. I'll add one.

@jquense
Copy link
Member

jquense commented Apr 6, 2016

LGTM, up to you if you want to take any of my comments, they are super minor.

I do want to make sure we loop back around on that annoying Dropdown addon issue at some point, but there is no need to solve it in this PR

@taion taion merged commit c56d8cf into react-bootstrap:next Apr 6, 2016
@taion taion deleted the inputs branch April 6, 2016 19:18
@Anahkiasen
Copy link

Anahkiasen commented Apr 20, 2016

I like new API, it's powerful and flexible and allows a lot of edge cases, but is deprecating the Input API necessary? It offers simplicity and ease of use for most use cases, in particular faced with the new API which is so verbose in comparaison:

Before

<Input type="text" label="Username" labelClassName="col-lg-2" wrapperClassName="col-lg-10" addonAfter="foo" />

After

<FormGroup>
    <Col lg={2}>
        <ControlLabel>Username</ControlLabel>
    </Col>
    <Col lg={10}>
        <InputGroup>
            <FormControl type="text" />
            <InputGroup.Addon>foo</InputGroup.Addon>
        </InputGroup>
    </Col>
</FormGroup>

I need 11 lines to express what I could do in one, on long forms that quickly accumulates to gigantic components. Again, I like the new API, and I'll probably need it at times, but can't the old one be kept as a shortcut to it, like it's the case for some other components (Dropdown IIRC)?

@taion
Copy link
Member Author

taion commented Apr 20, 2016

@Anahkiasen The idea is that you wrap this up into your own "field group" components, as relevant for your forms. The problem is that <Input> is too prescriptive, and was awkward for exactly your case. I'd wrap up what you have into something like <FieldGroup>.

@Anahkiasen
Copy link

Yes that's already what I ended up doing actually, and seen in that light it makes a lot more sense. Guess it just takes some getting used to – it's just the initial fear of the massive rewrite that kind of panicked me.

@taion
Copy link
Member Author

taion commented Apr 20, 2016

We should probably document that part better.

@patsissons
Copy link

How does one apply validation to a stand alone FormControl outside of a FormGroup with these changes?

@taion
Copy link
Member Author

taion commented May 6, 2016

Bootstrap doesn't have validation states for standalone form controls. They only apply to groups. You've never been able to apply validation states to standalone form controls.

@patsissons
Copy link

I guess i was just hacking it together before, i had previously just done something like <Input standalone bsStyle='error' ... /> to accomplish this. It's not a big deal to transition, just means a bit more verbosity.

@taion
Copy link
Member Author

taion commented May 6, 2016

If we're missing something I'd like to know it, but there is no e.g. .form-control.has-success styling in Bootstrap.

@patsissons
Copy link

I don't think you're missing something, I'm pretty sure i was just using a non-standard method of input validation.

@idolize
Copy link
Member

idolize commented May 17, 2016

I totally agree the new API is good and more flexible, but it'd be nice to have a bit more of an upgrade guide/path for large codebases with a lot of <Input> elements. Right now I'd like to essentially make my own <Input> wrapper that (mostly) replicates the old behavior (I know Input still exists, but it's on the chopping block).

I'd be happy to contribute such a guide if others agree it'd be helpful.

@taion
Copy link
Member Author

taion commented May 17, 2016

@idolize We need to write this up, but the recommended upgrade path is to write your own <Input>. The idea behind this API is that it offers a more flexible low-level abstraction to build the actual field group the user wants.

@idolize
Copy link
Member

idolize commented May 17, 2016

@taion Totally get that, and I agree it's a better API. I just think the upgrade path for existing codebases using Input is a little difficult right now, and the changelog only really points to a PR. When I go through the upgrade process I can write up a more in-depth guide we can add to CHANGELOG or wherever if it'd be helpful.

@taion
Copy link
Member Author

taion commented May 17, 2016

Might work in the component docs too – more visible that way.

@zerkms
Copy link
Contributor

zerkms commented May 23, 2016

The <Input> component deprecation looks like a step back: the releases prior to v0.29 encapsulated the dirty details about bootstrap, which was great. You take a library to do exactly that: to get a generic components that render into complicated markup.

Now everything is exposed back: now a developer needs to care about form groups again, about separated ControlLabels and so on.

What I expressed before with 7 lines of JSX and a single Input component now requires 11 lines and FormControl, FormGroup, ControlLabel, HelpBlock, InputGroup this many components.

@taion
Copy link
Member Author

taion commented May 23, 2016

The idea is that you wrap that up yourself – the old API was awful for things like horizontal and inline form groups.

@frontsideair
Copy link

Any suggestions on migrating a codebase with a lot of <Input>s from 0.28.* to 0.29.*?

@taion
Copy link
Member Author

taion commented May 24, 2016

Write our own equivalent of the old <Input>, tailored to your needs.

@Bazze
Copy link

Bazze commented Jul 29, 2016

People mention writing your own wrapper class since updating a large code base will take a lot of time, however I haven't seen any actual implementations. I thought I'd share my drop-in replacement which works fine for all the usages of Input in my app: https://gist.github.com/Bazze/81cf778d8843948977421bea5c8cdfee

@taion
Copy link
Member Author

taion commented Jul 29, 2016

We have a minimal example in http://react-bootstrap.github.io/components.html#forms-controls as well.

Point being that (1) this is very little code and (2) it's hard to make it properly one-size-fits-all without making it have like two dozen props like the old one, so we're going to hold off on trying to ship anything like that for now.

@Sigfried
Copy link

Sorry to be dense. In @taion 's reference to http://react-bootstrap.github.io/components.html#forms-controls above, the radio buttons in the doc example don't act like a radio group, more than one can be selected at a time. So, for people like me having a hard time following the whole conversation, is that because we have to implement only-one-at-a-time group behavior ourselves, or is it an oversight in the doc example? Thanks.

@Sigfried
Copy link

@jbroadice
Copy link

jbroadice commented Apr 4, 2017

Thanks @Bazze for posting your <Input /> drop-in. ❤️

I slightly updated it to 'iron out' a few quirks and add a few missing props that existed previously.

Here's the gist: <Input /> drop-in.*

*Note: Depends on classnames package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants