-
Notifications
You must be signed in to change notification settings - Fork 56
Open
Labels
Description
This is a brainstorm of my idea for https://trello.com/c/1hNDoqon/74-ability-to-add-field-configuration-modifiers
It would probably replace the need for #102; I think this is more flexible and means we don't have to deal with crazy generic statics.
Thoughts @bendetat @MattDavies @zabulus?
// Create this class (happy to field better naming ideas)
public class FormFieldOutput<TModel, T>
{
public FormFieldOutput(FieldParent parent)
{
Parent = parent;
}
public FieldParent Parent { get; private set; }
public IFieldGeneratorHandler<TModel, T> Handler { get; set; }
public IFieldConfiguration Configuration { get; set; }
public IFormTemplate Template { get; set; }
public ModelMetadata Metadata { get; set; }
public ReadonlyFieldConfiguration GetReadonlyConfiguration()
{
return new ReadonlyFieldConfiguration(Configuration);
}
}
// Change DefaultFieldGenerator.PrepareFieldConfiguration to:
public FormFieldOutput<TModel, T> PrepareField(IFieldConfiguration fieldConfiguration, FieldParent fieldParent)
{
var field = new FormFieldOutput(fieldParent)
{
Handler = FieldGeneratorHandlersRouter<TModel, T>.GetHandler(this),
Configuration = fieldConfiguration ?? new FieldConfiguration(),
Template = Template,
Metadata = Metadata
}
// This call could result in the handler, field config, template or metadata being changed on the fly for this field
// In order to make things more testable / extendable we could put the conventions on the IForm object instead of in a static?
FieldConventions.ForEach(c => c.Apply(field));
field.Handler.PrepareFieldConfiguration(fieldConfiguration);
field.Template.PrepareFieldConfiguration(this, handler, fieldConfiguration, fieldParent);
return field;
}
// These conventions will be defined by default (but can be removed), which were in the above method previously:
public class ReadonlyFieldsConvention : IFormConvention
{
public void Apply<TModel, T>(FormFieldOutput<TModel, T> field)
{
if (field.IsReadOnly)
field.Configuration.Readonly();
}
}
public class FormatStringConvention : IFormConvention
{
public void Apply<TModel, T>(FormFieldOutput<TModel, T> field)
{
if (!string.IsNullOrEmpty(field.Metadata.EditFormatString) && string.IsNullOrEmpty(field.Configuration.FormatString))
field.Configuration.WithFormatString(field.Metadata.EditFormatString);
}
}
public class NoneDisplayTextConvention : IFormConvention
{
public void Apply<TModel, T>(FormFieldOutput<TModel, T> field)
{
if (!string.IsNullOrEmpty(field.Metadata.NullDisplayText) && string.IsNullOrEmpty(field.Configuration.NoneString))
field.Configuration.WithNoneAs(field.Metadata.NullDisplayText);
}
}
// And people can create and register their own conventions like this:
FieldConventions.Add(new AddCalendarToDateFieldsConvention());
...
public class AddCalendarToDateFieldsConvention : IFormConvention
{
public void Apply<TModel, T>(FormFieldOutput<TModel, T> field)
{
if (typeof(T) == typeof(DateTime) || typeof(T) == typeof(DateTimeOffset))
field.Configuration.AddClass("datepicker").WithFormatString("{0:dd/MM/yyyy}");
}
}