Closed steph643 closed 9 years ago
I think you're right. The label
field could easily be replaced by a helper, like {{capitalize field}}
, and it could be up to the user how they want to convert field names to labels in the template.
There are some cool features in simple-schema, but I think the default schema handling in the forms package should probably be focused on making sure data is valid, not providing content to templates.
One interesting case is using the allowedValues
from simple-schema to determine what values to show in a select element. I think it makes sense in that case to get the options from the schema itself, rather than just checking that the value is within the allowed ones on validation. But this is actually handled manually when someone creates an element, using the {{schema}}
helper, so I guess that's different.
Regardless, it seems like one area where tighter coupling is actually necessary, and I'm sure there are others. Although perhaps (as you've mentioned) all of those types of things could be generated using a separate generate
lib that accepts a schema and returns the values--rather than having that functionality baked into the schema library or the form library. And perhaps I could build that as a sort of facade between simple-schema and forms, or between the check
lib and forms:
Generate.config({
labels: {
transform: 'camelToCapitalized',
wrapperTag: 'label',
overrides: {
'awesomeName': 'AWESOME! Name'
}
}
});
var content = Generate.generateContent(mySchema); // if (mySchema instanceof SimpleSchema) ... else ...
I don't have full visibility on this, but I have the feeling this is another trap.
You are talking about using allowedValues
to get options, but what about internationalization?
If users want complex label generation from schema, they can already do this (I guess):
MySchema = new SimpleSchema({
firstName: {
type: String,
label: function () {
return Session.get("lang") == "de" ? "Vorname" : "first name";
}
}
});
Alternatively, if users want to decouple label generation from the schema, they can write an external module by themselves. I think your package should only ensure this module can be easily plugged in.
steph643 said: "I don't have full visibility on this, but I have the feeling this is another trap."
One of the greatest comments ever!
I think there could be an abstraction boundary here somewhere. Looking at things from within the 'action' method, what are the sets of expectations that would make sense there? I see two possibilities:
1) You are given an object that may not be structured like your db schema, but that may have undergone some validation. It's up to you to finish the validation, if necessary, and convert the object into something that your db likes. Where you specified the rules for validation could have been several places, such as the template itself or a schema object of some kind. This 'form schema' may not have anything to do with your db schema, and may not even be written in the same format.
OR
2) You are given an object who's structure matches the structure of your db. This object has usually been fully validated by this point. The structure of the data object has been gleaned from a detailed schema associated with the db. The mapping between the form and the data is guided by both the schema and hints contained within the template, such as composite field names ("name.favoriteColors.color").
Maybe the library could be structured such that #1 is the core functionality, and #2 is an add-on feature that comes along later? Seems like Forms is pretty much already doing #1 now. But reading forums, people are tired of always having to close the impedance gap between their forms and db, and would love #2.
Currently it's somewhere between the two--in practice, I think it already plays out well.
Form blocks can be used with or without a schema. But the package assumes that if a schema exists, it's a complete schema for the form. A form can't be submitted unless all data from elements is valid.
If you don't use a schema, the form block will still run the action function when the form is submitted, and you can still get data manually from the DOM if you want that way using the els
argument.
I'm not really trying to offer automatic transformation based on somebody's SimpleSchema in this package. I expect users of the package to share what they've created (via component packages or on a dedicated website) so that it's easy for others to create various elements, and I'd be happy to write some examples in the docs.
In fact, SimpleSchema support might be moved into a separate package in version 2.0.0
, opening up support for other types of schema validation using an API from the core package. In that case, support for some type of automatic transformation may be offered, although it's still dubious because I don't want to have to write logic to cover a bunch of different DOM configurations in elements--that would lead me into the same type of rabbit hole you mentioned AutoForm being in, not to mention it only saves people a few lines of code.
Currently, I wouldn't encourage using schemas that match any type of complex DB structure for your forms. I've been using schemas designed around how I want to validate data from user inputs, and they're all single-level schemas, because the package hasn't yet implemented support for the dot-notation format used by SimpleSchema.
I think your approach is right on. Given what you just said, I think a simple way to declare form schema that's not tied to another library might be best. Keep the focus on the building of reusable components. Offer lots of examples, and maybe some built in components that lack much style-related markup but add useful behaviors. Then users could wrap those with their own templates. Encourage component libraries to really separate the behavior tags and code from the look and feel tags. This is another area where autoform has failed.
Currently, I wouldn't encourage using schemas that match any type of complex DB structure for your forms.
I use schemas from my not-so-basic DB structure and it works pretty well so far.
I think the reason is that templates:forms
allows, very naturally, to use only a few fields from a complex schema. This is not so easy with autoForm
. What I like about templates:forms
is that it doesn't try to "understand" the full schema, but only "sees" the fields I want it to use.
I would like templates:forms
to remain transparent, to not make any assumption, to not transform anything, to just allow me, from the action
callback and the element helpers, to pull, from the schema, things I previously put in there myself.
:+1:
You have just closed this, but I see no change in the doc. What did you decide?
I'm working on a new version of the docs (based off your suggested changes) and I have something about this in those. I meant to push out the docs last night when I closed this but I was just too tired. Should have it all up by later today.
Great, thanks!
Thank you for all your help. Also, let me know if nested schemas work out for you!
{{label}}
makes a call to the simple-schema function that generates a label, hence returning a label even if the user hasn't set one explicitly.{{schema.label}}
returns the label field of the schema, hence returning undefined if the user hasn't set one explicitly. I think this is confusing.My opinion is that neither a schema package nor a form package should include a label-generation feature. However, because you support simple-schema, people will probably expect you to support it (same problem you have with
clean()
).Until you can get rid of simple-schema, I suggest you rename
{{label}}
into{{generateLabel}}
and explain in the doc what it does.As far as I'm concerned, I will stop using
{{label}}
and replace it with{{#if schema.label}}{{schema.label}}{{else}}{{field}}{{/if}}
.