Skip to content
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

Bootstrap version of plexus-form #30

Open
martijnvermaat opened this issue Apr 28, 2015 · 18 comments
Open

Bootstrap version of plexus-form #30

martijnvermaat opened this issue Apr 28, 2015 · 18 comments

Comments

@martijnvermaat
Copy link
Contributor

I'd like to use plexus-form with bootstrap styling. Some custom CSS classes would probably not suffice and I would prefer to use React Bootstrap.

Providing custom Bootstrapped inputComponent hints might get us quite far, but the downside is that they would need to be set in the schema (for every field).

Ideally I would create a light wrapper library around plexus-form which would override the input components. With the inputComponent hints approach this would require parsing and interpreting the schema (something plexus-form already does and I don't want to repeat).

The easy way out would be to just fork the entire library and modify it a bit, but I would really like to prevent that.

Any thoughts on what the best approach would be?

@bebraw
Copy link
Contributor

bebraw commented Apr 28, 2015

I've kludged plexus-form and Pure together at Reactabular. In the end it was just a matter of implementing custom field and section wrappers. I apply Pure classes there and it just works.

I believe you could use a similar approach with Bootstrap. It probably isn't quite what you have in mind but my approach is simple and it works. Best of all it might not require any modifications to underlying libraries. You would just implement a wrapper of your own. Of course that could be released as a library of its own.

@martijnvermaat
Copy link
Contributor Author

As suggested by @bebraw I gave the wrappers another try. For now my example is just a simple form with an input field and a select field, and I managed to get the exact same layout as I had with plain Bootstrap.

Bootstrap requires CSS classes on the form elements themselves, and for that I had to modify the render of InputField and Selection slightly to pass through a className property. With that in place, I can set the appropriate class using cloneElement in my field wrapper.

Although it feels a little bit fragile, this limited example works for me. I haven't looked at sections, other field types, or validation yet.

@odf
Copy link
Contributor

odf commented Apr 29, 2015

I think my ideal solution would be for plexus-form to take the schema plus a collection of React components (or rather classes) used as "building blocks" and wire those building blocks together according to the schema.

Internally, the building blocks we use are the individual input handlers, which users can at present only override via the inputComponent hint, and the field and section wrappers, which users can override by passing props into Form. As discussed earlier, if we provided a mechanism for specifying custom input handlers "form-wide" based on types and formats, I imagine we'd be a good step further.

@bebraw
Copy link
Contributor

bebraw commented Apr 29, 2015

Maybe a good first step would be to push the field components out of the core? Now they are pretty well split up already. When using the library, you would pick one of these field sets in use. Here's an API demo:

var fields = require('plexus-fields');
var Form = require('plexus-form');

...
<Form fields={fields} types={{number: customNumberField}} ... />

plexus-form would expect certain components and certain convention. As long as you go with that, things should just work. This would allow you to customize the base components heavily. If you want to keep backwards-compatibility, you can just use plexus-fields by default internally. In case you go that way, the API could use that for default fields in case some fields are missing from the definition.

That types property is there to allow customization of field mapping based on type. You could use this to override default behavior. This feels like a separate issue, though, and we can discuss that later in detail. There are things like enum to worry about.

@bebraw
Copy link
Contributor

bebraw commented May 4, 2015

I thought customization a little further. I realized what I described isn't enough for all cases. For instance in an app I'm developing I'll need to replace enums with a dynamic component that performs searches against backend (predictive input). This means there probably should be means to replace components on field level (match against field name).

@odf
Copy link
Contributor

odf commented May 6, 2015

What to match against seems like a tricky question. In plexus-form's "parent" project, we will be needing both auto-complete fields and dynamic pull-down menus, as well. It might be nice to be able to tag properties which need this functionality as, say, "predictive", in the schema, and then have the field-list builder use a pull-down if enum is also present, and an auto-complete text field otherwise.

It's starting to look like we'd want a generic matching algorithm that can match against anything the user wants it to (by, say, passing in a pattern object). Then again, maybe that's a bit too much effort for a simple form builder?

@bebraw
Copy link
Contributor

bebraw commented May 6, 2015

"predictive" would work for me. I think the problem with this approach is that it ties something very specific to plexus-form core. What if you want to customize the rendered form some other way (ie. color picker for a color field (just a string internally))?

This is why I think it would go a long way to add extension point per field level at least (others can be built on top of this!). I mean if you can map a custom component per field name, you can customize plexus-form a lot without having to touch the core. From plexus-form point of view it should work the same as long as the custom components use the API it expects.

You can see this type of thinking in action at reactabular. I've kept the API very limited on purpose. As a result I managed to push a lot of nasty problems to user space (not my problem :) ).

@odf
Copy link
Contributor

odf commented May 6, 2015

Oh, I didn't mean to hard-code something like "predictive" into the core, just the ability to add tags to fields and then match by tags instead of directly by field names. It would be a slight generalization of what inputComponent already does.

That said, matching against field names may be good enough for most applications. There's a potential problem when one composes a schema from existing ones and some field names occur more than once in different contexts, but that seems manageable.

@bebraw
Copy link
Contributor

bebraw commented May 6, 2015

Oh, I didn't mean to hard-code something like "predictive" into the core, just the ability to add tags to fields and then match by tags instead of directly by field names. It would be a slight generalization of what inputComponent already does.

Alright. 👍

That said, matching against field names may be good enough for most applications. There's a potential problem when one composes a schema from existing ones and some field names occur more than once in different contexts, but that seems manageable.

Shouldn't field names be unique by definition as they are object keys? I might be missing something obvious here.

@odf
Copy link
Contributor

odf commented May 6, 2015

Sure, field names are unique as long as you only match against top level fields. When you have nesting, though, that's no longer necessarily true. One option might be to match against paths, instead.

@bebraw
Copy link
Contributor

bebraw commented May 6, 2015

One option might be to match against paths, instead.

Sure. That would work.

@martijnvermaat
Copy link
Contributor Author

This would be nice. The downside is that you would still have to provide this on a per-field basis. It would also be nice if you could (perhaps in addition?) provide a custom component for all fields of a certain type. And than indeed just matching on type, might not be good enough (e.g., a date picker might want to match on type=string and format=date).

@bebraw
Copy link
Contributor

bebraw commented May 6, 2015

This would be nice. The downside is that you would still have to provide this on a per-field basis. It would also be nice if you could (perhaps in addition?) provide a custom component for all fields of a certain type. And than indeed just matching on type, might not be good enough (e.g., a date picker might want to match on type=string and format=date).

The thing is, having per field customization would open doors for abstractions like this on user land. You could easily write a thinger that goes through the definition, extracts fields per type and attached some component to them. Of course the plexus-form can come with a helper like this if it's a common enough need.

@martijnvermaat
Copy link
Contributor Author

You could easily write a thinger that goes through the definition, extracts fields per type and attached some component to them.

But this you can already do by adding x-hints/form/inputComponent to the schema for those fields?

In any case I don't like the idea of user land having to intepret the schema, it would duplicate logic that is already in plexus-form. Some helper as you mention would definitely good then.

@bebraw
Copy link
Contributor

bebraw commented May 6, 2015

But this you can already do by adding x-hints/form/inputComponent to the schema for those fields?

Thanks! Somehow missed that. Yeah, this solves my use case very well. 👍

@martijnvermaat
Copy link
Contributor Author

Preprocessing the schema by adding x-hints/form/inputComponent definitions, I managed to get the result I wanted (limited to the form features I needed for now).

I had to apply two patches to plexus-form:

  1. Pass the field type to the wrapper: martijnvermaat/plexus-form@ebf688d
  2. Pass the field schema to user defined input components: martijnvermaat/plexus-form@dccf191

Number 1 was needed because depending on schema.type, wrapper structure can change (e.g., checkbox vs text input).

Number 2 was needed because my custom <select> field needs access to schema.enum.

@odf Would you take these patches?

@odf
Copy link
Contributor

odf commented May 17, 2015

@martijnvermaat Yes, that sounds good.

@BDiehr
Copy link

BDiehr commented Aug 6, 2015

I've been scanning around the forks but I haven't found anything promising yet... Has anyone created an open sourced bootstrapified version of plexus-forms yet? Figured it was worth asking :)

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

No branches or pull requests

4 participants