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>();
// 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!
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!
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With