Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC - Populating a form dynamically through the database

I am porting a search application from Classic ASP to ASP.NET MVC2. One of hte pages is a dynamically populated search form that is broken up into 4 categories, each with 2 rows.

The client is able to uncheck options for each of these categories. When this happens, each category is dynamically repopulated top to bottom, left to right. The person who programmed the Classic ASP version setup a subroutine that searched through the database (which has a boolean field for each search field) and then returned an array. He then took the array and called another subroutine that looped through the array and then generated each of the categories.

Right now, the only thing I can think of is to create a model that has methods for each of the categories, each of which return a List. A simple example would be:

class SearchPageOrganizer {

    // Declare SearchFields object
    private SearchFields fields;

    // Contructor; instantiates SearchFields object
    public SearchPageOrganizer(SearchFields searchFields) {
       this.fields =  searchFields;
    }

    // Gets a list of fields active in the characteristics category
    public List<String> GetCharactersticsList() {
        List<String> list = new List<String&gt();

        // Check if the Color field is active
        if (fields.Color) {
            list.Add("Color");
        }

        // Check if the Size field is active
        if (fields.Size) {
            list.Add("Size");
        }

        // Return the list
        return list;
    }
}

Then what I could do is split the list according to the size of each row, and then loop through each the list and call a user control that is able to render the HTML dynamically based on a name parameter.

The problem with this technique is that, for some odd reason, it feels like I am not doing this in the most simplistic way. For anyone who reads this, is there an easier way in which you would implement this?

Thanks!

like image 929
cfitzarl Avatar asked Aug 29 '10 20:08

cfitzarl


2 Answers

This is something I've been wanting to investigate for sometime. Having dabbled in Rails, I got spoiled with the view binding to the model.

It seems that there is a helper in the MVC space called Html.EditorForModel(). This helper generates a form for the model to which the view is bound. I'm not exactly sure what it would do in your situation, but it certainly would be interesting to see the output and perhaps it might give you some ideas for a personal implementation.

Good luck!

like image 150
Steven Hoff Avatar answered Sep 21 '22 07:09

Steven Hoff


Here is what I would recommend. Create a div that contains the dynamic content and put that content in a partial view. In this case there would be a partial view called Products.ascx

 <div id="ProductsContent">
    <% Html.RenderPartial("Products"); %>
 </div>

Call a javascript function when a category checkbox is clicked.

<input id="Category_1" type="checkbox" onclick="CategoryCheckChanged(1)" />
<input id="Category_2" type="checkbox" onclick="CategoryCheckChanged(2)" />
<input id="Category_3" type="checkbox" onclick="CategoryCheckChanged(3)" />

use JQuery to detect the value of the checkbox, then post to the server. In the example below my controller name is called Products. The information returned from the server is the updated partial view, which replaces the div contents.

function CheckChanged(id) 
{
    var bChecked = $("#Category_"+id).attr("checked");

    var value = 0;
    if(bChecked) value=1;

     $.post('<%= Url.Action("CategoryChanged","Products") %>'
        , { value: value, categoryid: id }
        , function(data) {
           if (data.success) {
              alert("Sweet !")
              //update the div with the new content
              $('#ProductsContent').html(data.newcontent);
           }
           else {
              alert("Bummer:" + data.msg);
           }

        }, "json");

}

Here is the CategoryChanged function in ProductsController

  [HttpPost]
  public ActionResult CategoryChanged(int value, int id)
  {
     try
     {
        //Save the change to the database
        SaveChangedCategoryValueToDatabase(id,value);

        //Create your View Model
        MyProductsViewModel vm = new MyProductsViewModel();

        return Json(new { success = true, newcontent =
           MyViewHelper.RenderPartialToString(this.ControllerContext, 
           "~/Views/Products/Products.ascx", 
           new ViewDataDictionary(vm), new TempDataDictionary()) });

     }
     catch(SystemException ex)
     {
         return Json(new { success = false, msg = ex.Message });
     }

  }

and finally... The helper function that takes renders a partial view to a string.

public static class MyViewHelper
{
  public static string RenderPartialToString(ControllerContext context
     , string partialViewName
     , ViewDataDictionary viewData
     , TempDataDictionary tempData)
  {
     ViewEngineResult result = 
        ViewEngines.Engines.FindPartialView(context, partialViewName);

     if (result.View != null)
     {
        StringBuilder sb = new StringBuilder();
        using (StringWriter sw = new StringWriter(sb))
        {
           using (HtmlTextWriter output = new HtmlTextWriter(sw))
           {
              ViewContext viewContext = new ViewContext(
                 context, result.View, viewData, tempData, output);
              result.View.Render(viewContext, output);
           }
        }

        return sb.ToString();
     }

     return String.Empty;
  }
}
like image 21
Craig Howard Avatar answered Sep 18 '22 07:09

Craig Howard