MRCollective / ChameleonForms

Shape-shifting your forms experience in ASP.NET Core MVC
MIT License
254 stars 56 forks source link

Adding proper extensibility to ChameleonForms #107

Open robdmoore opened 9 years ago

robdmoore commented 9 years ago

There is currently an open PR at #104 that I can't merge because I want to figure out how extensibility and reusability will work in ChameleonForms going forward to make sure that the PR aligns with the direction. ChameleonForms has been 1.0 for a while now and I've used it a lot so I have a fair idea of all the scenarios where it didn't do something I wanted it to do now. Below is a list of URLs to ideas and discussions that have been documented in the past and below that is the list of features I think I want. I'm not sure on syntax yet, but some of the links below contain some ideas.

I'd like input from @MattDavies @Royce @joshka @zabulus @bendetat if you have any. I'm also going to ponder this and hopefully we can settle on some syntax ideas and a feature list to drive the future direction of this project and allow willing contributors like @zabulus (thanks so much for being so keen dude - it's appreciated!) to be able to contribute while being informed of the direction of the project and allow Matt and I to provide quicker PR merging.

Context

Would love feedback and ideas.

robdmoore commented 9 years ago

Happy to arrange a Skype call too if peeps are keen

robdmoore commented 9 years ago

Collation of initial ideas

Ability to output a form using a view model type that is completely different from the model type of the page

using (Html.BeginChameleonForm<TDifferentViewModel>() {}

Behaviour would be that it recreates a HtmlHelper like in #91 with a model populated with the default constructor.

using (Html.BeginChameleonForm(new TDifferentViewModel{Property1 = "Default value"}) {}

Same, but you can take control of newing up the model type.

See also #95

Ability to output a form using a sub-property of the model type of the page and bind back to the type of the sub-property

As per #91:

using (Html.BeginChameleonFormFor(m => m.Writable)) {}

Alternatively, as per https://trello.com/c/VGmRwd68/156-ability-to-use-subview-models-within-the-current-page:

@using (var f = Html.PostSubViewModel(m => m.Sub).BeginChameleonForm())) {}

Ability to output a form using a sub-property of the model type of the page and bind back to the page model type

As per https://trello.com/c/VGmRwd68/156-ability-to-use-subview-models-within-the-current-page:

@using (var f = Html.UseSubViewModel(m => m.Sub).BeginChameleonForm())) {}

Ability to output a section against a complex property of a type T using a partial view

As per #113:

// set up a partial, form fields should be in context "Whatever" for the field names so postback works
// x=>x should work if you want the whole model
// Should be able to do it from the form or a section
@f.PartialFor(x => x.Whatever, "PartialViewModel");
@s.PartialFor(x => x.Whatever, "PartialViewModel");
// it would be cool to be able to create a section using the field, so it would call BeginSectionFor in a using statement around the inclusion of the partial
@f.PartialSectionFor(x => x.Whatever, "PartialViewModel");
@s.PartialSectionFor(x => x.Whatever, "PartialViewModel");

// ...

// In the partial view itself to get access to the form or section you could do something like the following.
// Should we drop the Chameleon or can people come up with different, better names...
@this.ChameleonSection() // from #113
@Html.ChameleonSection() // Similar to what's suggested in #62

@this.ChamleonForm()
@Html.ChamleonForm()

// And for those situations where you want the partial to support form or section you could have:
@this.IsChameleonSection()
@Html.IsChameleonSection()
@this.IsChameleonForm()
@Html.IsChameleonForm()

Ability to output a field using a partial view

@s.FieldFor(m => m.Property).RenderPartial("_PartialView")
// or, maybe:
@s.FieldFor(m => m.Property).Partial("_PartialView")
// or, maybe:
@s.PartialFor(m => m.Property, "_PartialView")

Ability to specify a partial view for a type by convention as well as inline in the page

If we configure the partial on the IFieldConfiguration then doing the convention is easy.

ReSharper intellisense on partial view name

Easy with ReSharper annotations (https://www.jetbrains.com/resharper/webhelp/Reference__Code_Annotation_Attributes.html#AspMvcPartialViewAttribute)

Ability to use Editor Templates to generate just the editor html - should be able to be used for complex types as well as simple types, should be able to specified via [UiHint], inline in the view, by convention and possibly for all unknown types as the default fallback?

@s.FieldFor(m => m.Property).WithEditorTemplate("Template")
// or, maybe:
@s.EditorFor(m => m.Property, "Template")

[UIHint] should work with FieldFor. Using EditorFor in default field generator handler is an idea too.

Ability to modify / swap out handlers, template, field configuration based on conventions that can be applied globally

Covered by separate conversation in #106

joshka commented 9 years ago

Rob, this all looks fairly sensible to me. I'm not using Chameleon for anything right now, so don't have any skin in the game.

MattDavies commented 9 years ago

I'm okay with your thinking on this so far - I'll have a look through trello as well and see if I think there's anything else we really need to focus on.

Would be more than happy to jump on a Skype call as well if anyone aside from us is interested in this :)

robdmoore commented 9 years ago

This work is currently blocked by @MattDavies and I finding the time to get it started. We will start by reviewing, tweaking and pulling in #113 and then add issues with clear descriptions and #upforgrabs tags for the rest to unblock it and allow people to contribute. Thanks everyone for your patience so far (especially @zabulus!) - Matt and I have been under the pump with personal stuff lately.