2

I want to be able to have list for my model which in Create view could be edited. It would be one to many relation. For example: If I had Client model with possibility of creating shopping list for this person, but list would has it's properties too :

public class Client 
{
public int ClientID {get; set}
public string Name {get; set;}
public virtual ICollection<Product> Product {get; set;}
}

public class Product 
{
public int ProductID {get; set;}
public int ClientID {get; set;}
public string ProductName {get; set;}
public string Description {get; set;}
public virtual Client Client {get; set;}
}

In create view for Client I want to give him name and be able to add products without any limit and after I would have Client with list of products - save him. And of course then I want to be able to view Client with list of products in Details view.

What would be the best approach for this? Please advise :)

0

1 Answer 1

1

The best approach is the entity framework and the codefirst method, which I introduced in the example below. Only I made a small change in the Client class and changed the Product to Products.

public class Client 
{
   public Client()
   {
      Products = new List<Product>();
   }
   public string Name {get; set;}
   public virtual ICollection<Product> Products {get; set;}
}

Add Data In DataBase

Client client = new Client();
client.Name = "Client 1";


Product product1 = new Product() { Description = "desc 1", ProductName = "product 1" };
Product product2 = new Product() { Description = "desc 2", ProductName = "product 2" };
Product product3 = new Product() { Description = "desc 3", ProductName = "product 3" };

client.Products.Add(product1);
client.Products.Add(product2);
client.Products.Add(product3);
db.Clients.Add(client);
db.SaveChanges();

Real Example

Just me in this example add the data to the controller in the database which you have to do in the Repository layer.

Your Model

public class Client
{
   [Key]
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public int ID { get; set; }
   public string Name { get; set; }
   public virtual ICollection<Product> Products { get; set; }
}

public class Product
{
   [Key]
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public int ID { get; set; }
   public string ProductName { get; set; }
   public string Description { get; set; }
   public virtual Client Client { get; set; }
}

Tour Context

class yourContextName : DbContext
{
     public yourContextName() : base("yourConnectionName")
     {
     }

    
     protected override void OnModelCreating(DbModelBuilder modelBuilder)
     {
         base.OnModelCreating(modelBuilder);
         modelBuilder.Entity<Client>().Property(c => c.ID)
        .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
         modelBuilder.Entity<Product>().Property(c => c.ID)
        .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
     }
     public DbSet<Client> Clients
     {
         get;
         set;
     }

     public DbSet<Product> Products
     {
         get;
         set;
     }
}

Your Controller

[HttpGet]
public ActionResult AddProduct()
{
    var client = new Client();
    client.Name = "Client 1";
    return View(client);
}
[HttpPost]
public ActionResult AddProduct(Client client, string[] ProductNames, string[] Descriptions)
{
    client.Products = new List<Product>();
    for(int i=0;i<ProductNames.Length;i++)
    {
         if(!string.IsNullOrEmpty(ProductNames[i]))
         {
             Product product = new Product() { Description = 
             Descriptions[i], ProductName = ProductNames[i] };
             client.Products.Add(product);
         }
     }
    //add data to database
    db.Clients.Add(client);
    db.SaveChanges();

    
    return View(client);
}

Your View

@model StackOverFlowMVC.Controllers.Client

@{
    ViewBag.Title = "AddProduct";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>AddProduct</h2>
@using (Html.BeginForm("AddProduct", "Home", FormMethod.Post, new { id = "myform" }))
{
    <label>Client Name : </label>
    @Html.TextBoxFor(model => model.Name)
    <br />
    <hr />
    <br />
    <div id="prItems">
        <section id="row1" num="1">
            <div style="margin:10px;">
                <label>Product Name 1 : </label>
                @Html.TextBox("ProductNames",null)
            </div>
            <div style="margin:10px;">
                <label>Product Descr 1 : </label>
                @Html.TextBox("Descriptions", null)
            </div>
            <input type="button" class="RowDelete" value="-" onclick="removeRow(1)" />
            <hr />
        </section>
    </div>
    <button id="btnAddRow">Add Product</button>
    <input type="submit" value="submit" id="btnsubmit" />
}

@section scripts{
    <script>
        $(document).ready(function () {
            $('#ProductNames').val('');
            $('#Descriptions').val('');
        });
        $('#btnAddRow').click(function (e) {
            e.preventDefault();
            var row = "<section><div style = 'margin:10px;'><label></label><input type='text'></div><div style='margin:10px;'><label></label><input type='text'></div><input type='button' class='RowDelete' value='-'/><hr /></section>";
            $('#prItems').append(row);
            orderRow();
        })


        function removeRow(num) {
            $('#prItems section').each(function (idx) {
                if ($(this).attr('num') == num) {
                    $(this).remove();
                }
            });
            orderRow();
        }
        function orderRow() {
            var rowCount = $('#prItems section').length;
            if (rowCount > 0) {
                $('#prItems section').each(function (idx) {
                    var num = idx + 1;
                    $(this).attr('id', 'row' + num);
                    $(this).attr('num', num);

                    $(this).children().children().nextAll().slice(0, 1).prev().text('Product Name ' + num + " : ");
                    $(this).children().children().nextAll().slice(0, 1).attr('name', 'ProductNames');


                    $(this).children().next().children().nextAll().slice(0, 1).prev().text('Product Descr ' + num + " : ");
                    $(this).children().next().children().nextAll().slice(0, 1).attr('name', 'Descriptions');

                
                    $(this).children().next().next().slice(0, 1).attr('onclick', 'removeRow(' + num + ')');
                });
            }
        }
    </script>
}
Sign up to request clarification or add additional context in comments.

22 Comments

In the solution you have provided you have specified that there will be 5 products. I want this to be flexible, maybe input and next to it plus button which would add new product and clear input so I could add another product. Is it possible?
You can create dynamic fields with JavaScript or jQuery and send the information to the action according to the same pattern. I imported 5 products to clarify the concept.
You have to manage all the activities. Anything can be done
Do you have any examples, posts, which would help me do this?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.