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

#434 - Render empty array item fields when minItems is specified #484

Merged
merged 5 commits into from
Feb 24, 2017

Conversation

Reggino
Copy link
Contributor

@Reggino Reggino commented Feb 22, 2017

Reasons for making this change

Trying to get my feet wet with this library and doing something useful on the way 😄

Implemented #434

BTW thanks for this awesome stuff!

Checklist

  • I'm updating documentation
    • I've checked the rendering of the Markdown text I've added
    • If I'm adding a new section, I've updated the Table of Content
  • I'm adding or updating code
    • I've added and/or updated tests
    • I've updated docs if needed
  • I'm adding a new feature
    • I've updated the playground with an example use of the feature

Copy link
Contributor

@glasserc glasserc left a comment

Choose a reason for hiding this comment

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

Hi, thanks for your enthusiasm! I'm new to the project myself so I'll defer to @n1k0 on any review, but since he's probably asleep right now, here's what I noticed.

src/utils.js Outdated

case "array":
if (schema.minItems) {
return new Array(schema.minItems).fill(schema.items.default);
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this involve a recursive call to computeDefaults ? For example, what if the items are an object or have $ref ?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Indeed.

Copy link
Contributor Author

@Reggino Reggino Feb 23, 2017

Choose a reason for hiding this comment

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

Thanks, fixed

const {node} = createFormComponent({schema: complexSchema, formData: { }});

const inputs = node.querySelectorAll("input[type=text]");
expect(inputs.length).eql(4);
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we test that the right default value is chosen? I see that there's no other tests for the "default" behavior for ArrayField, so this might be excessive.

Should we test that merging formData with defaults works correctly?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IMHO formData and defaults can really be merged in case of an array: it is either set or not set. When set, the form should honor the given value. When not set it may compute a sane default.

I've added a test for this behaviour

Copy link
Collaborator

@n1k0 n1k0 left a comment

Choose a reason for hiding this comment

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

I checked the branch but couldn't make the new feature work in the playground. Am I missing something? Could you please update the playground with a sample use of it? Thanks!

src/utils.js Outdated

case "array":
if (schema.minItems) {
return new Array(schema.minItems).fill(schema.items.default);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Indeed.

@Reggino
Copy link
Contributor Author

Reggino commented Feb 23, 2017

I've added an example to the playground.

// whenever a value is set, honor it!
form = createFormComponent({schema: complexSchema, formData: {foo: []}});
inputs = form.node.querySelectorAll("input[type=text]");
expect(inputs.length).eql(0);
Copy link
Collaborator

Choose a reason for hiding this comment

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

It would be better to distinguish between the two sets of assertions here, so we're better informed when one of these fails.

This can usually be achieved by either mounting a single component per it test.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're completely right. I've updated the PR

@n1k0
Copy link
Collaborator

n1k0 commented Feb 23, 2017

Also, tested the patch again with the updated playground, works great!

src/utils.js Outdated
if (schema.minItems) {
return new Array(schema.minItems).fill(computeDefaults(schema.items, defaults, definitions));
}
return defaults || [];
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do we fallback to an empty array here? I understand it may be confusing but we need to distinguish between an empty array and no array value defined at all. I'd suggest we just return defaults here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IMHO computeDefaults would ideally be the only place where defaults are "made up". I actually tried to remove this line:
https://github.com/mozilla-services/react-jsonschema-form/blob/master/src/components/fields/ArrayField.js#L153

But other tests would break. However, it would be more clear when all defaults would originate in computeDefaults

Copy link
Contributor Author

Choose a reason for hiding this comment

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

BTW when no value would be defined at all, that would lead to [] due to the defaultProps in ArrayField.js

Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree, we'll have to work to make this more consistent in the future. Meanwhile here, I'm pretty sure we could remove the whole return defaults || []; line without breaking anything, as that would match previous behavior, don't you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True. I've updated the PR

Copy link
Contributor Author

@Reggino Reggino left a comment

Choose a reason for hiding this comment

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

Should be ok now :-)

Copy link
Contributor

@glasserc glasserc left a comment

Choose a reason for hiding this comment

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

Thanks!

@n1k0
Copy link
Collaborator

n1k0 commented Feb 24, 2017

Thanks++

n1k0 added a commit that referenced this pull request Mar 21, 2017
New features

* Add support for rows attribute of textarea widget. (#450)
* #434 - Render empty array item fields when minItems is specified (#484)
* Add a "has-danger" class to the form error list (#502)
* Show description for boolean fields (#498)
* Fix #488: Add a custom Form ErrorList prop.

Bugfixes

* Fix impossibility to use stateful ArrayFieldTeplate comp. (#519)
* Centralized shouldComponentUpdate handling in SchemaField (#490)
@n1k0
Copy link
Collaborator

n1k0 commented Mar 21, 2017

Released in v0.44.0.

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.

3 participants