Master Detail View

4 posts, 0 answers
  1. Arun Kumar
    Arun Kumar avatar
    60 posts
    Member since:
    Nov 2009

    Posted 07 Jul 2014 Link to this post

    Hi All,

    I want to create contacts view. My model is:

    public class Contact
    {
        public Contact()
        {
            Documents = new HashSet<Document>();
        }

        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string ContactNo { get; set; }
        public string EmailId { get; set; }
        public string Address { get; set; }
        public string Notes { get; set; }
        public ICollection<Document> Documents { get; set; }
    }

    public class Document
    {
        public Document() { }

        public int Id { get; set; }
        public int ContactId { get; set; }
        public string DocumentNo { get; set; }
        public string DocumentType { get; set; }
        public byte[] FileContent { get; set; }
        public string FileName { get; set; }
        public int ContentLength { get; set; }
    }

    I have created view with Contact details and Grid for documents. Actually I am new to MVC so I am searched internet how to achieve this. But I cannot find any workable solution yet. I do not know how to add one or more document and persist document details in grid.  What I am trying to achieve is save contact information with uploaded documents (one or more) while submit the form.


    Thanks in advance.
  2. Nikolay Rusev
    Admin
    Nikolay Rusev avatar
    2285 posts

    Posted 09 Jul 2014 Link to this post

    Hello Arun,

    I recommend you going through the following articles which explains how to implement hierarchy and CRUD operations:
     - Client Hierarchy
     - Ajax Editing

    You can also check the following forum thread for sample implementation of upload as editor: upload-in-grid-custom-editor.

    Regards,
    Nikolay Rusev
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Arun Kumar
    Arun Kumar avatar
    60 posts
    Member since:
    Nov 2009

    Posted 09 Jul 2014 in reply to Nikolay Rusev Link to this post

    Hi Nikolay,

    Thanks for your response. I have already tried the links you provided. Please look it in to the code and suggest how do I achieve it.

    Create.chtml:

    @model Contacts.Models.Contact
     
    @{
        ViewBag.Title = "Create";
    }
     
    <h2>Create</h2>
     
     
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
     
        <div class="form-horizontal">
            <h4>Contact</h4>
            <hr />
            @Html.ValidationSummary(true, "", new { @class = "text-danger" })
            <div class="form-group">
                @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
                </div>
            </div>
     
            <div class="form-group">
                @Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
                </div>
            </div>
     
            <div class="form-group">
                @Html.LabelFor(model => model.ContactNo, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.ContactNo, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.ContactNo, "", new { @class = "text-danger" })
                </div>
            </div>
     
            <div class="form-group">
                @Html.LabelFor(model => model.EmailId, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.EmailId, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.EmailId, "", new { @class = "text-danger" })
                </div>
            </div>
     
            <div class="form-group">
                @Html.LabelFor(model => model.Address, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.Address, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.Address, "", new { @class = "text-danger" })
                </div>
            </div>
     
            <div class="form-group">
                @Html.LabelFor(model => model.Notes, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.Notes, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.Notes, "", new { @class = "text-danger" })
                </div>
            </div>
     
            @(Html.Kendo().Grid(Model.Documents)
                .Name("Documents")
                .Columns(columns =>
                {
                    columns.Bound(d => d.DocumentNo).Width(100).ClientTemplate("#= DocumentNo #" +
                        "<input type='hidden' name='Documents[#= index(data)#].DocumentNo' value='#= DocumentNo #' />"
                      );
     
                    columns.Bound(d => d.DocumentType).Width(150).ClientTemplate("#= DocumentType #" +
                        "<input type='hidden' name='Documents[#= index(data)#].DocumentType' value='#= DocumentType #' />"
                      );
     
                    columns.Command(cmd => { cmd.Edit(); cmd.Destroy(); });
     
                })
                .DataSource(dataSource => dataSource
                    .Ajax()
                    .Events(events => events.Error("onError"))
                    .Model(model => model.Id(d => d.Id))
                    .Create(create => create.Action("AddDocument", "Contacts"))
                    .Update(update => update.Action("UpdateDocument", "Contacts"))
                    .Destroy(destroy => destroy.Action("DeleteDocument", "Contacts"))
                )
                .ToolBar(toolBar => toolBar.Create())
                .Editable(editable => editable.Mode(GridEditMode.PopUp))
            )
     
            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Create" class="btn btn-default" />
                </div>
            </div>
        </div>
    }
     
    <div>
        @Html.ActionLink("Back to List", "Index")
    </div>
     
    @section Scripts {
     
        <script>
     
            function index(dataItem) {
                var data = $("#Documents").data("kendoGrid").dataSource.data();
                return data.indexOf(dataItem);
            }
     
            function onError(e) {
                if (e.errors) {
                    var message = "Errors:\n";
                    $.each(e.errors, function (key, value) {
                        if ('errors' in value) {
                            $.each(value.errors, function () {
                                message += this + "\n";
                            });
                        }
                    });
                    alert(message);
                }
            }
     
        </script>
     
        @Scripts.Render("~/bundles/jqueryval")
     
    }

    ContactsController:

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Entity;
    using System.Linq;
    using System.Net;
    using System.Web;
    using System.Web.Mvc;
    using Contacts.DataContext;
    using Contacts.Models;
    using Kendo.Mvc.UI;
    using Kendo.Mvc.Extensions;
     
     
    namespace Contacts.Controllers
    {
        public class ContactsController : Controller
        {
     
            private ContactDb db = new ContactDb();
     
     
            public ActionResult Index()
            {
                return View(db.Contacts.ToList());
            }
     
     
            public ActionResult Details(int? id)
            {
                if (id == null)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
                Contact contact = db.Contacts.Find(id);
                if (contact == null)
                {
                    return HttpNotFound();
                }
                return View(contact);
            }
     
     
            public ActionResult Create()
            {
                var model = new Contact();
     
                model.Documents.Add(new Document { DocumentNo = "", DocumentType = "" });
     
                return View(model);
            }
     
     
            [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult Create([Bind(Include = "Id,FirstName,LastName,ContactNo,EmailId,Address,Notes")] Contact contact)
            {
     
                //Here, contact.Documents is NULL
     
                if (ModelState.IsValid)
                {
                    db.Contacts.Add(contact);
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
     
                return View(contact);
            }
     
     
            public ActionResult Edit(int? id)
            {
                if (id == null)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
                Contact contact = db.Contacts.Find(id);
                if (contact == null)
                {
                    return HttpNotFound();
                }
                return View(contact);
            }
     
     
            [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult Edit([Bind(Include = "Id,FirstName,LastName,ContactNo,EmailId,Address,Notes")] Contact contact)
            {
                if (ModelState.IsValid)
                {
                    db.Entry(contact).State = EntityState.Modified;
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
                return View(contact);
            }
     
     
            public ActionResult Delete(int? id)
            {
                if (id == null)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
                Contact contact = db.Contacts.Find(id);
                if (contact == null)
                {
                    return HttpNotFound();
                }
                return View(contact);
            }
     
     
            [HttpPost, ActionName("Delete")]
            [ValidateAntiForgeryToken]
            public ActionResult DeleteConfirmed(int id)
            {
                Contact contact = db.Contacts.Find(id);
                db.Contacts.Remove(contact);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
     
     
            [HttpPost]
            public ActionResult AddDocument([DataSourceRequest]DataSourceRequest request, Document model)
            {
                if (model != null && ModelState.IsValid)
                {
                    //How do I add it to Model ?
                    //Since contact model data is not saved in database
                }
     
                return Json(new[] { model }.ToDataSourceResult(request, ModelState));
            }
     
     
            [HttpPost]
            public ActionResult UpdateDocument([DataSourceRequest]DataSourceRequest request, Document model)
            {
                if (model != null && ModelState.IsValid)
                {
                    //How do I update ?
                    //Since contact model data is not saved in database
                }
     
                return Json(new[] { model }.ToDataSourceResult(request, ModelState));
            }
     
     
            [HttpPost]
            public ActionResult DeleteDocument([DataSourceRequest]DataSourceRequest request, Document model)
            {
                if (model != null && ModelState.IsValid)
                {
                    //How do I delete ?
                    //Since contact model data is not saved in database
                }
     
                return Json(new[] { model }.ToDataSourceResult(request, ModelState));
            }
     
     
            protected override void Dispose(bool disposing)
            {
                if (disposing)
                {
                    db.Dispose();
                }
                base.Dispose(disposing);
            }
     
        }
    }

    Thanks in advance.
  5. Nikolay Rusev
    Admin
    Nikolay Rusev avatar
    2285 posts

    Posted 11 Jul 2014 Link to this post

    Hello Arun,

    Unfortunately from the provided code we are not able to assemble a runnable project. Thus I've created an  example using Upload in Grid edit form.

    Can you modify it so that it replicates the issue which you are facing?

    Regards,
    Nikolay Rusev
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
Back to Top
UI for ASP.NET MVC is VS 2017 Ready