简体   繁体   中英

Accessing dynamically added HTML controls in ASP.net MVC

I have a problem which I'm unable to solve so any help would be appreciated. I have a view in which I'm dynamically adding textboxes (depending of a value chosen in dropdownlist).

Basically, I'm entering data for the product which depending of the category it belongs to has specific attributes added to it. For example, if the product is soft dring it could have following attributes: type of packaging, flavor, volume, etc. while some other product like cell phone may have attributes like: weight, RAM, CPU clock, CPU type, etc.

This is how the database looks like:

数据库中的表

Dynamically creating controls isn't a problem and it is done with this code:

<script type="text/javascript">
    $(document).ready(function () {          

        $("#ProductCategoryId").change(function () {
            if ($("#ProductCategoryId").val() != "") {
                var options = {};
                options.url = "http://localhost:59649/Product/GetProductCategoryAttributes";
                options.type = "POST";
                options.data = JSON.stringify({ id: $("#ProductCategoryId").val() });
                options.dataType = "json";
                options.contentType = "application/json";
                options.success = function (productCategoryAttributes) {
                    $("#atributtes").empty();
                    for (var i = 0; i < productCategoryAttributes.length; i++) {
                        $("#atributi").append("<div class='editor-label'><label>" + productCategoryAttributes[i].Name + "</label></div>")
                        .append("<div class='editor-field'><input class='text-box single-line' id='" + productCategoryAttributes[i].Name + "' name='" + productCategoryAttributes[i].Name + "' type='text'>");
                    }
                };
                options.error = function () { alert("Error retrieving data!"); };
                $.ajax(options);
            }
            else {
                $("#atributtes").empty();
            }
        });
    });
</script>

Method in controller that retrieves ProductAttributeCategory names depending of ProductCategoryId selected:

    public JsonResult GetProductCategoryAttributes(int id)
    {
        var productCategoryAttributes = db.ProductCategoryAttribute
            .Where(p => p.ProductCategoryId == id)
            .Select(p => new { Name = p.Name, p.DisplayOrder })
            .OrderBy(p => p.DisplayOrder)
            .ToList();

        return Json(productCategoryAttributes, JsonRequestBehavior.AllowGet);
    }

Controller code for POST:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(Product product)
    {
        if (ModelState.IsValid)
        {
            db.Product.Add(product);
            db.SaveChanges();

            var productCategoryAttributes = db.ProductCategoryAttribute
                .Where(p => p.ProductCategoryId == product.ProductCategoryId)
                .OrderBy(p => p.DisplayOrder);

            foreach (ProductCategoryAttribute productCategoryAttribute in productCategoryAttributes)
            {
                //Find HTML element that matches productCategoryAttribute.Name
                ProductProductCategoryAttribute productCategoryAttributeValue = new ProductProductCategoryAttribute();
                productCategoryAttributeValue.ProductId = product.ProductId;
                //productCategoryAttributeValue.ProductCategoryAttributeId = Find HTML element that matches ProductCategoryAttributeID and pass its id here
                //productCategoryAttributeValue.Value = Find HTML element that matches ProductCategoryAttributeID and pass its value here

                db.ProductProductCategoryAttribute.Add(productCategoryAttributeValue);
                db.SaveChanges();

            }               
            return RedirectToAction("Index");
        }

        ViewBag.LanguageId = new SelectList(db.Language, "LanguageId", "Name", product.LanguageId);
        ViewBag.ProductCategoryId = new SelectList(db.ProductCategory, "ProductCategoryId", "Name", product.ProductCategoryId);
        return View(product);
    }

Product model:

    public partial class Product
{
    public Product()
    {
        this.ProductPhoto = new HashSet<ProductPhoto>();
        this.ProductProductCategoryAttribute = new HashSet<ProductProductCategoryAttribute>();
    }

    public int ProductId { get; set; }
    public int LanguageId { get; set; }
    public int ProductCategoryId { get; set; }
    public string Name { get; set; }
    public string EAN { get; set; }
    public string Description { get; set; }

    public virtual Language Language { get; set; }
    public virtual ProductCategory ProductCategory { get; set; }
    public virtual ICollection<ProductPhoto> ProductPhoto { get; set; }
    public virtual ICollection<ProductProductCategoryAttribute> ProductProductCategoryAttribute { get; set; }
}

ProductCategory model:

    public partial class ProductCategory
{
    public ProductCategory()
    {
        this.Product = new HashSet<Product>();
        this.ProductCategoryAttribute = new HashSet<ProductCategoryAttribute>();
    }

    public int ProductCategoryId { get; set; }
    public int LanguageId { get; set; }
    public string Name { get; set; }
    public string PhotoLocation { get; set; }
    public int DisplayOrder { get; set; }
    public bool Active { get; set; }

    public virtual Language Language { get; set; }
    public virtual ICollection<Product> Product { get; set; }
    public virtual ICollection<ProductCategoryAttribute> ProductCategoryAttribute { get; set; }
}

ProductCategoryAttribute model:

    public partial class ProductCategoryAttribute
{
    public ProductCategoryAttribute()
    {
        this.ProductProductCategoryAttribute = new HashSet<ProductProductCategoryAttribute>();
    }

    public int ProductCategoryAttributeId { get; set; }
    public int ProductCategoryId { get; set; }
    public string Name { get; set; }
    public string MetaName { get; set; }
    public string SymbolLocation { get; set; }
    public int DisplayOrder { get; set; }
    public bool Active { get; set; }

    public virtual ProductCategory ProductCategory { get; set; }
    public virtual ICollection<ProductProductCategoryAttribute> ProductProductCategoryAttribute { get; set; }
}

What I can't figure out is how to get the values from those dynamically created textboxes. Pseudocode (inside the controller) would be something like this:

  1. Get the ProductCategoryId of the product
  2. List all the attributes belonging to the selected product category
  3. For each attribute find the appropriate textbox inside the view and get the value entered
  4. Save the value to the database

I'm fairly new to the MVC so my approach may be wrong. Feel free to correct me.

It's very hard to read your code so here is a simplified version that should help you. Suppose you have these two models:

public class ProductCategory
{
   public int CategoryId { get; set; }
   public string CategoryName { get; set; }
}

public class Product
{
   public Product()
   {
      Categories = new List<ProductCategory>();
   }

   public int ProductId {get;set;}
   public string ProductName { get; set; }
   public IEnumerable<ProductCategory> Categories { get; set; }
}

If these where your models then then the name attribute of your dynamically added textbox should be:

<input type="textbox" name="Categories[i].CategoryName" />

You can safely ignore the id attribute since name attribute is enough for proper model mapping/binding. Whatever value you enter in the textbox should map into an instance of a ProductCategory's CategoryName in the list of Categories attached to the Product model...

Thank you both of you. I've found a quick and, as it seems, dirty way of accomplishing this.

Basically, you can access any HTML control by using:

var value = Request["controlName"];

That is how I was able to get values from the form. I don't know if this is the right way but it sure worked for me. Any suggestion for improving this is more than welcome.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM