This is a migrated thread and some comments may be shown as answers.

Help populate second grid by selection in first grid

0 Answers 158 Views
Grid
This is a migrated thread and some comments may be shown as answers.
andrew
Top achievements
Rank 1
andrew asked on 18 Jul 2012, 12:14 PM
Hi,

I am trying to create a permissions view for my MVC 4 application.

What I want to achieve is that the selection made on the users table, populates the payrolls this person can access in a second table, then by selecting a payroll from the second table I would like it to display the permissions that user has within the selected payroll. So exactly like this http://demos.telerik.com/aspnet-ajax/grid/examples/clientmasterdetails/defaultcs.aspx but three tables instead of 2.

I can get a grid to populate with the users but where I am strugling is getting the selected user to query the payrolls and populate the payrolls table. I am quite new to all this so I am not quite sure how the selection gets the data and renders the grid? Does this call an ajax action in the view controller? And how is the second grid element then rendered? Does it re-render the first grid with the list of users again or will this persits?

My controller so far is like this NB the ReadPay and ReadPay Functions and all the ViewData in the Index action are my attempts to get this to work so please ignore them if they are wrong and point me in the right direction if possible please:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PayPlate.Models;
using PayPlate.DAL;
using PagedList;
 
namespace PayPlate.Controllers
{
    public class UserController : Controller
    {
        UnitOfWork unitOfWork = new UnitOfWork();
 
           public ActionResult Index(Int32 ? uid, Int32 ? pid)
        {
            ViewData["Users"] = Read();
            if (uid == null)
            {
                uid = unitOfWork.UserRepository.Get().FirstOrDefault().UserID;
            }
            ViewData["uid"] = uid;
            ViewData["Payrolls"] = ReadPay(uid.Value);
            if (pid == null)
            {
                pid = unitOfWork.UserRepository.Get(i => i.UserID == uid).Single().Permissions.Select(p => p.PayrollID).Distinct().FirstOrDefault();
            }
            ViewData["pid"] = pid;
            ViewData["Permissions"] = ReadPerm(uid.Value, pid.Value);
            return View();
        }
 
        public IEnumerable<Payroll> ReadPay(Int32 uid)
        {
            var pays = unitOfWork.UserRepository.Get(i => i.UserID == uid).Single().Permissions.Select(p => p.Payroll).Distinct();
                // Use a view model to avoid serializing internal Entity Framework properties as JSON
                pays = pays.Select(p => new Payroll
                {
                    PayrollID = p.PayrollID,
                    Title = p.Title,
                    C21Name = p.C21Name,
                    Server = p.Server,
                    Port = p.Port,
                    Connection = p.Connection
                })
                .ToList();
 
            return pays;
        }
 
        public IEnumerable<Permission> ReadPerm(Int32 uid, Int32 pid)
        {
            var viewModel = new PayrollIndexData();
            var selectedPay = viewModel.Payrolls.Where(x => x.PayrollID == pid).Single();
            var usersPay = selectedPay.Permissions.Where(u => u.UserID == uid);
            viewModel.Permissions = usersPay;
            var perms = viewModel.Permissions;
            return perms;
        }
       
        /// <summary>
        /// Creates new products by inserting the data posted by the Kendo Grid in the database.
        /// </summary>
        /// <param name="products">The products created by the user.</param>
        /// <returns>The inserted products so the Kendo Grid is aware of the database generated ProductID</returns>
        [HttpPost]
        public ActionResult Create(IEnumerable<User> _users)
        {
            var result = new List<User>();
 
            //Iterate all created products which are posted by the Kendo Grid
            foreach (var user in _users)
            {
                // Create a new Product entity and set its properties from productViewModel
                var _user = new User
                {
                    NetLogin = user.NetLogin,
                    EmpNumber = user.EmpNumber,
                    Forename = user.Forename,
                    Surname = user.Surname,
                    Active = user.Active
                };
 
                // store the product in the result
                result.Add(_user);
 
                // Add the entity
                unitOfWork.UserRepository.Insert(_user);
            }
 
            // Insert all created products to the database
            unitOfWork.Save();
 
            // Return the inserted products - the Kendo Grid needs their ProductID which is generated by SQL server during insertion
 
            return Json(result.Select(p => new User
            {
                UserID = p.UserID,
                NetLogin = p.NetLogin,
                EmpNumber = p.EmpNumber,
                Forename = p.Forename,
                Surname = p.Surname,
                Active = p.Active
            })
            .ToList());
        }
 
        /// <summary>
        /// Reads the available products to provide data for the Kendo Grid
        /// </summary>
        /// <returns>All available products as JSON</returns>
        [HttpPost]
        public ActionResult Read()
        {
            var _users = unitOfWork.UserRepository.Get()
                // Use a view model to avoid serializing internal Entity Framework properties as JSON
                .Select(p => new User
                {
                    UserID = p.UserID,
                    NetLogin = p.NetLogin,
                    EmpNumber = p.EmpNumber,
                    Forename = p.Forename,
                    Surname = p.Surname,
                    Active = p.Active
                })
                .ToList();
 
            return Json(_users);
        }
 
        /// <summary>
        /// Updates existing products by updating the database with the data posted by the Kendo Grid.
        /// </summary>
        /// <param name="products">The products updated by the user</param>
        [HttpPost]
        public ActionResult Update(IEnumerable<User> _users)
        {
            //Iterate all created products which are posted by the Kendo Grid
            foreach (var user in _users)
            {
                // Attach the entity
                unitOfWork.UserRepository.Update(user);
            }
 
            // Save all updated products to the database
            unitOfWork.Save();
 
            //Return emtpy result
            return Json(null);
        }
 
        /// <summary>
        /// Destroys existing products by deleting them from the database.
        /// </summary>
        /// <param name="products">The products deleted by the user</param>
        [HttpPost]
        public ActionResult Destroy(IEnumerable<User> _users)
        {
            //Iterate all destroyed products which are posted by the Kendo Grid
            foreach (var user in _users)
            {
                // Delete the entity
                unitOfWork.UserRepository.Delete(user);
            }
 
            // Delete the products from the database
            unitOfWork.Save();
 
            //Return emtpy result
            return Json(null);
        }
 
        //
        // GET: /User/Details/5
        public ViewResult Details(Int32? id, Int32? payrollID, IEnumerable<User> _users)
        {
            var viewModel = new PayrollIndexData();
 
            foreach (var _user in _users)
            {
                viewModel.Users = unitOfWork.UserRepository.Get(i => i.UserID == _user.UserID);
            }
 
            if (id != null)
            {
                ViewBag.UserID = id.Value;
                viewModel.Payrolls = unitOfWork.UserRepository.Get(i => i.UserID == id.Value).Single().Permissions.Select(p => p.Payroll).Distinct();
            }
 
            if (payrollID != null)
            {
                ViewBag.PayrollID = payrollID.Value;
                var selectedPayroll = viewModel.Payrolls.Where(x => x.PayrollID == payrollID).Single();
                var usersPayroll = selectedPayroll.Permissions.Where(u => u.UserID == id.Value);
                viewModel.Permissions = usersPayroll;
            }
            return View(viewModel);
        }
 
        protected override void Dispose(bool disposing)
        {
            unitOfWork.Dispose();
            base.Dispose(disposing);
        }
    }
}

This is my view so far, again the second grid code and the selectable: true in the first grid are my attempts to get this to work:

@section CustomHeader {
    @* kendo.common.min.css contains common CSS rules used by all Kendo themes *@
    @* kendo.silver.min.css contains the "Blue Opal" Kendo theme *@
}
<h2>Users</h2>
@* The DIV where the Kendo grid will be initialized *@
<div id="grid"></div>
<script>
$(function () {
    $("#grid").kendoGrid({
        height: 425,
        selectable: "true",
        columns: [
            { field: "NetLogin", width: "60px" },
            { field: "EmpNumber", width: "60px" },
            { field: "Forename", width: "90px" },
            { field: "Surname", width: "90px" },
            { field: "Active", width: "45px" },
            { command: "destroy", title: "Command", width: "120px", groupable: false, filterable: false }
        ],
        change: function() {
            var row = this.select();
            var id = row.data("id");
            $("#log").html("selected row with id= " + id);
            var secondGrid = $("#grid2").data("kendoGrid");
            var row = secondGrid.table.find('tr[data-id="' + id + '"]');
            secondGrid.select(row);
        },
 
        editable: true, // enable editing
        sortable: true,
        pageable: true,
        filterable: true,
        groupable: true,
        resizable: true,
        reorderable: true,
        toolbar: ["create", "save", "cancel"], // specify toolbar commands
        dataSource: {
        pageSize: 20,
            schema: {
                model: { // define the model of the data source. Required for validation and property types.
                    id: "UserID",
                    fields: {
                        UserID: { editable: false, nullable: true },
                        NetLogin: { validation: { required: true } },
                        EmpNumber: { validation: { required: true } },
                        Forename: { validation: { required: true } },
                        Surname: { validation: { required: true } },
                        Active: { validation: { required: false } }
                    }
                }
            },
            batch: true, // enable batch editing - changes will be saved when the user clicks the "Save changes" button
            transport: {
                create: {
                    url: "@Url.Action("Create", "User")", //specify the URL which should create new records. This is the Create method of the HomeController.
                    type: "POST" //use HTTP POST request as the default GET is not allowed for ASMX
                },
                read: {
                    url: "@Url.Action("Read", "User")", //specify the URL which should return the records. This is the Read method of the HomeController.
                    type: "POST" //use HTTP POST request as by default GET is not allowed by ASP.NET MVC
                },
                update: {
                    url:"@Url.Action("Update", "User")", //specify the URL which should update the records. This is the Update method of the HomeController.
                    type: "POST" //use HTTP POST request as by default GET is not allowed by ASP.NET MVC
                },
                destroy: {
                    url: "@Url.Action("Destroy", "User")", //specify the URL which should destroy the records. This is the Destroy method of the HomeController.
                    type: "POST" //use HTTP POST request as by default GET is not allowed by ASP.NET MVC
                },
                parameterMap: function(data, operation) {
                    if (operation != "read") {
                        // post the products so the ASP.NET DefaultModelBinder will understand them:
 
                        // _users[0].Value="value"
                        // _users[0].UserID =1
                        // _users[1].Value="value"
                        // _users[1].UserID =1
 
                        var result = {};
 
                        for (var i = 0; i < data.models.length; i++) {
                            var _user = data.models[i];
 
                            for (var member in _user) {
                                result["_users[" + i + "]." + member] = _user[member];
                            }
                        }
 
                        return result;
                    }
                }
            }
        }
    });
});
</script>
 
<h2>Payrolls</h2>
@* The DIV where the Kendo grid will be initialized *@
<div id="grid2"></div>
<script>
    $(function () {
        $("#grid2").kendoGrid({
            height: 425,
            columns: [
            { field: "PayrollID", width: "45px" },
            { field: "Title", width: "100px" },
            { field: "C21Name", width: "70px" },
            { field: "Server", width: "70px" },
            { field: "Port", width: "30px" },
            { field: "Connection", width: "130px" }
        ],
            sortable: true,
            pageable: true,
            filterable: true,
            groupable: true,
            resizable: true,
            reorderable: true,
            dataSource: {
                pageSize: 20,
                schema: {
                    model: { // define the model of the data source. Required for validation and property types.
                        id: "PayrollID",
                        fields: {
                            PayrollID: { editable: false, nullable: true },
                            Title: { validation: { required: true} },
                            C21Name: { validation: { required: true} },
                            Server: { validation: { required: true} },
                            Port: { validation: { required: true} },
                            Connection: { validation: { required: true} }
                        }
                    }
                },
 
                parameterMap: function (data, operation) {
                    if (operation != "read") {
                        // post the products so the ASP.NET DefaultModelBinder will understand them:
 
                        // agrps[0].Value="value"
                        // agrps[0].PayrollID =1
                        // agrps[1].Value="value"
                        // agrps[1].PayrollID =1
 
                        var result = {};
 
                        for (var i = 0; i < data.models.length; i++) {
                            var pay = data.models[i];
 
                            for (var member in pay) {
                                result["pays[" + i + "]." + member] = pay[member];
                            }
                        }
 
                        return result;
                    }
                }
            }
        });
    });
</script>


Your help will be greatly appreciated!

Andy

No answers yet. Maybe you can help?

Tags
Grid
Asked by
andrew
Top achievements
Rank 1
Share this question
or