mcintyre321 / FormFactory

MVC5, Core or standalone - Generate rich HTML5 forms from your ViewModels, or build them programatically
http://formfactoryaspmvc.azurewebsites.net/
MIT License
304 stars 103 forks source link

Dynamic forms from Propertyvm #93

Closed learner291 closed 4 years ago

learner291 commented 4 years ago

I am new to FormFactory and also learning MVC at the same time. I am trying to create a dynamic form using PropertyVm. I was able to create form when I use following code in Index.cshtml view.

`@{

        PropertyVm[] formModel = new[]
        {
                new PropertyVm(typeof(DateTime) , "date")
                {
                    DisplayName = "Your birthday",
                    NotOptional =true,
                    GetCustomAttributes = () => new object[] { new DateAttribute() }
                },
                new PropertyVm(typeof(string) , "textmessage")
                {
                    DisplayName = "Type a message:",
                    NotOptional =false,
                    GetCustomAttributes = () => new object[] { new MultilineTextAttribute(),  new DisplayAttribute() { Prompt = "placeholder??" }, new System.ComponentModel.DescriptionAttribute("Type anything here.")  },
                },
                 new PropertyVm(typeof(string) , "number")
                {
                    DisplayName = "Select a number",
                    NotOptional =false,
                    Choices = new List<string>() {"one","two","three","four" },
                },
                new PropertyVm(typeof(string), "username")
                {
                    DisplayName = "Username",
                    NotOptional = true,
                    Suggestions = new List<string>() { "holy poo" },
                },
                new PropertyVm(typeof(string), "password")
                {
                    DisplayName = "Password",
                    NotOptional = true,
                    GetCustomAttributes = () => new object[]{ new PasswordAttribute() }
                },
                new PropertyVm(typeof(string), "os")
                {
                    DisplayName = "Operating System",
                    NotOptional = true,
                    Choices = new List<string>() {"OSX", "IOS", "Windows", "Android"},
                    Value = "Windows", //Preselect windows
                    GetCustomAttributes = () => new object[] {new RadioAttribute(), new System.ComponentModel.DescriptionAttribute("Make a choice above.") }
                 },
                new PropertyVm(typeof(bool), "check")
                {
                    DisplayName = "Check if happy",
                    NotOptional = true,
                    Value = false, //Preselect false (unchecked)
                    GetCustomAttributes = () => new object[] {new FormFactory.Attributes.LabelOnRightAttribute() } // right label
                 },
                new PropertyVm(typeof(bool), "check2")
                {
                    DisplayName = "Check if sad",
                    Value = false, //Preselect false (unchecked)
                    NotOptional =true

                },new PropertyVm(typeof(object) , "Things")
                {
                    DisplayName = "Pick a thing",
                    NotOptional =true,
                    Choices = new List<object>
                        {
                        new PropertyVm(typeof(string) , "ThingOne")
                        {
                            IsHidden = true,
                            DisplayName = "Thing One"
                        },
                        new PropertyVm(typeof(string) , "ThingTwo")
                        {
                            IsHidden = true,
                            DisplayName = "Thing Two"
                        },
                    }
                }
          };

        @formModel.Render(Html)
    }`

Next step I am trying to do is pass above variable from Controller, once that is done then I will try to get data from the database to build the model. The code that I have in my controller and view is displayed below.

` public IActionResult Index() { PropertyVm[] formModel = new[] { new PropertyVm(typeof(DateTime) , "date") { DisplayName = "Your birthday", NotOptional =true, GetCustomAttributes = () => new object[] { new DateAttribute() } }, new PropertyVm(typeof(string) , "textmessage") { DisplayName = "Type a message:", NotOptional =false, GetCustomAttributes = () => new object[] { new MultilineTextAttribute(), new DisplayAttribute() { Prompt = "placeholder??" }, new System.ComponentModel.DescriptionAttribute("Type anything here.") }, }, new PropertyVm(typeof(string) , "number") { DisplayName = "Select a number", NotOptional =false, Choices = new List() {"one","two","three","four" }, }, new PropertyVm(typeof(string), "username") { DisplayName = "Username", NotOptional = true, Suggestions = new List() { "holy poo" }, }, new PropertyVm(typeof(string), "password") { DisplayName = "Password", NotOptional = true, GetCustomAttributes = () => new object[]{ new PasswordAttribute() } }, new PropertyVm(typeof(string), "os") { DisplayName = "Operating System", NotOptional = true, Choices = new List() {"OSX", "IOS", "Windows", "Android"}, Value = "Windows", //Preselect windows GetCustomAttributes = () => new object[] {new RadioAttribute(), new System.ComponentModel.DescriptionAttribute("Make a choice above.") } }, new PropertyVm(typeof(bool), "check") { DisplayName = "Check if happy", NotOptional = true, Value = false, //Preselect false (unchecked) GetCustomAttributes = () => new object[] {new FormFactory.Attributes.LabelOnRightAttribute() } // right label }, new PropertyVm(typeof(bool), "check2") { DisplayName = "Check if sad", Value = false, //Preselect false (unchecked) NotOptional =true

                },new PropertyVm(typeof(object) , "Things")
                {
                    DisplayName = "Pick a thing",
                    NotOptional =true,
                    Choices = new List<object>
                        {
                        new PropertyVm(typeof(string) , "ThingOne")
                        {
                            IsHidden = true,
                            DisplayName = "Thing One"
                        },
                        new PropertyVm(typeof(string) , "ThingTwo")
                        {
                            IsHidden = true,
                            DisplayName = "Thing Two"
                        },
                    }
                }
          };            
        ViewBag.Message = formModel;
        return View();
    }`

In my view

` @{ var formModel = ViewBag.Message;

        @formModel.Render(Html)
    }

`

However I am now getting following error. Can someone please let me know what I am doing incorrectly?

An unhandled exception occurred while processing the request. RuntimeBinderException: 'System.Array' does not contain a definition for 'Render' CallSite.Target(Closure , CallSite , object , IHtmlHelper ) System.Dynamic.UpdateDelegates.UpdateAndExecute2<T0, T1, TRet>(CallSite site, T0 arg0, T1 arg1) AspNetCore.Views_Home_Index.ExecuteAsync() in Index.cshtml + @formModel.Render(Html)

Davidcc commented 4 years ago

you might need references in your _ViewImports

@using FormFactory @using FormFactory.Attributes

learner291 commented 4 years ago

Thank you it has worked on my demo application. However, we are unable to use FormFactory as it seems that is not compatible with .net core 3 (https://github.com/mcintyre321/FormFactory/issues/89) which is what we are using in our production system, that is unfortunate as I was looking forward to exploring and using FormFactory.