Adding and Updating data - passing values for adding, skipping records unless new or edited

2 posts, 0 answers
  1. Andrew
    Andrew avatar
    4 posts
    Member since:
    Oct 2017

    Posted 07 Nov 2017 Link to this post

    I'm just getting started with the grid, but I'm up to the point where I can load the grid with data from my database and I can call methods that I expect to use for Inserting and Updating records. Here's the markup for the view with the grid:

    @using AdminAppII.Models
    @model AdminAppII.Models.UsersCustomEditTemplate

    @{
        ViewBag.Title = "Users";
    }

    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()

        <div class="form-horizontal">
            <div class="form-group">
                @Html.Label("Agency ID", new { @class = "control-label" })
                @Html.DropDownList("SelectedAgencyID", ViewBag.agencyList as SelectList, new { @class = "control-label" })
            </div>

            <div class="form-group">
                @(Html.Kendo().Grid<AdminAppII.Models.UsersCustomEditTemplate>()
                    .Name( "Grid")
                    .Columns( columns =>
                    {
                        // TODO replace widths here with server-side call if we want to read in these values from a config file
                        columns.Bound(c => c.AgentID).Width(100);
                        columns.Bound(c => c.AgencyID).Width(100);
                        columns.Bound(c => c.Active).Width(100);
                        columns.Bound(c => c.FirstName).Width(150);
                        columns.Bound(c => c.MiddleName).Width(150);
                        columns.Bound(c => c.LastName).Width(150);
                        columns.Bound(c => c.EmployeeID).Width(100);
                        columns.Bound(c => c.Username).Width(150);
                        columns.Bound(c => c.Email).Width(200);
                        columns.Bound(c => c.Roles).Width(300);
                        columns.Bound(c => c.BMA2Active).Width(100);
                        columns.Bound(c => c.UseADAuthentication).Width(100);
                        columns.Bound(c => c.ADUserName).Width(100);

                        columns.Command(cmd => cmd.Edit()).Width(100);
                    })
                    .ToolBar(toolBar =>
                        {
                            toolBar.Create();
                        })
                    .Pageable(pager => pager
                        .Input(true)
                    )
                    .Sortable()
                    .Scrollable(s => s.Height(500)) //////////////////////// hard coded height
                    .Filterable()
                    .DataSource( dataSource => dataSource
                        .Ajax()
                        .Model( model => model.Id(m => m.DeptType))
                        .Read( read => read.Action("Read","Home"))
                        .PageSize(40) /////////////////////////////////////// hard coded items per page
                        .Update(up => up.Action("UpdateAgency", "Home"))
                        .Create(create => create.Action("CreateAgency", "Home"))
                    )
                    .Resizable(resize => resize.Columns(true))
                    .Reorderable(reorder => reorder.Columns(true))
                    .HtmlAttributes(new { style = "height: 550px" })  /// does control the height
                    .Editable(ed => ed.Mode(GridEditMode.PopUp).TemplateName("UsersEditAdd"))
                )
            </div>
        </div>
        <div class="box wide">
            <a href="#" class="k-button" id="save" title="Saves changes like width and order. Need to click Load State to restore the changes.">Save State</a>
            <a href="#" class="k-button" id="load" title="Restores the state saved by the save state button.">Load State</a>
        </div>

    <script type="text/javascript">
        var gridData;
        // want to replace 'select' with at variable that captures the ID of the drop down
        // and make sure it works
        // see https://stackoverflow.com/questions/23873302/add-click-event-on-an-option-in-html-select-tag for the event code
        $('select').change(function () {
            var agencyID = $(this).val().toString();
            location = '/Home/Users?refreshData=true&agencyID=' + agencyID;
        });
    </script>
    <script type="text/javascript">

        $(function () {
            var grid = $("#Grid").data("kendoGrid");

            $("#save").click(function (e) {
                e.preventDefault();
                localStorage["kendo-grid-options"] = kendo.stringify(grid.getOptions());
            });

            $("#load").click(function (e) {
                e.preventDefault();
                var options = localStorage["kendo-grid-options"];
                if (options) {
                    grid.setOptions(JSON.parse(options));
                }
            });
        });
    </script>

     

    Here's the model:

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.ComponentModel.DataAnnotations;

    namespace AdminAppII.Models
    {
        public class UsersCustomEditTemplate
        {
            [Required]
            [Display(Name = "First Name")]
            public string FirstName { get; set; }

            [Display(Name = "Middle Name")]
            public string MiddleName { get; set; }

            [Required]
            [Display(Name = "Last Name")]
            public string LastName { get; set; }

            [Required]
            [Display(Name = "User Name")]
            public string Username { get; set; }

            [Display(Name = "Approval Email Address")]
            [DataType(DataType.EmailAddress)]
            public string Email { get; set; }

            [Display(Name = "EZLabor Code")]
            public string EZLaborCode { get; set; }

            [Display(Name = "Official Name")]
            public string OfficialName { get; set; }

            [Display(Name = "Dept Type")]
            public string DeptType { get; set; }

            [Display(Name = "Comm Start Date")]
            [DataType(DataType.Date)]
            public DateTime? CommStartDate { get; set; }

            [Display(Name = "Agent Date Added")]
            [DataType(DataType.Date)]
            public DateTime? AgentDateAdded { get; set; }

            [Display(Name = "New Registration Note")]
            public string NewRegistrationNote { get; set; }


            [Display(Name = "License Number")]
            public string LicenseNumber { get; set; }

            [Display(Name = "Agent ID")]
            [Required]
            public int AgentID { get; set; }


            [Display(Name = "Agency ID")]
            [Required]
            public int AgencyID { get; set; }

            [Display(Name = "Employee ID")]
            public int? EmployeeID { get; set; }
            
            [Display(Name = "Active")]
            public int? Active { get; set; }

            [Display(Name = "BMA2Active")]
            public int? BMA2Active { get; set; }

            [Display(Name = "Use AD Authentication")]
            public int? UseADAuthentication { get; set; }

            [Display(Name = "AD User Name")]
            public string ADUserName { get; set; }

            [Display(Name = "Roles")]
            public string Roles { get; set; }

            //[Display(Name = "")]
            //public string  { get; set; }

        }
    }

    Here are the two methods in the Home controller mentioned in the grid to be called for the Create and Update

    public ActionResult UpdateAgency([DataSourceRequest] DataSourceRequest dsRequest, UsersCustomEditTemplate agency)
            {
                if (agency != null && ModelState.IsValid)
                {
                    // do update; this method is called for every line in the grid
                }
                
                return Json(ModelState.ToDataSourceResult());
            }
            public ActionResult CreateAgency([DataSourceRequest] DataSourceRequest dsRequest, UsersCustomEditTemplate agency)
            {
                if (agency != null && ModelState.IsValid)
                {
                    // do update; this method is called for every line in the grid
                }

                return Json(ModelState.ToDataSourceResult());
            }

    And, Here's the custom editor view:

     

    @model AdminAppII.Models.UsersCustomEditTemplate
    <div class="popupEditor">
        <div class="form-horizontal">
            @Html.ValidationSummary(true, "", new { @class = "text-danger" })

            @Html.HiddenFor(model => model.AgencyID)
            @Html.HiddenFor(model => model.AgentID)

            <div class="form-group">
                @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label" })
                @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.MiddleName, htmlAttributes: new { @class = "control-label" })
                @Html.EditorFor(model => model.MiddleName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.MiddleName, "", new { @class = "text-danger" })
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label" })
                @Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.Username, htmlAttributes: new { @class = "control-label" })
                @Html.EditorFor(model => model.Username, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Username, "", new { @class = "text-danger" })
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label" })
                @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.EZLaborCode, htmlAttributes: new { @class = "control-label" })
                @Html.EditorFor(model => model.EZLaborCode, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.EZLaborCode, "", new { @class = "text-danger" })
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.OfficialName, htmlAttributes: new { @class = "control-label" })
                @Html.EditorFor(model => model.OfficialName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.OfficialName, "", new { @class = "text-danger" })
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.DeptType, htmlAttributes: new { @class = "control-label" })
                @Html.EditorFor(model => model.DeptType, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.DeptType, "", new { @class = "text-danger" })
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.CommStartDate, htmlAttributes: new { @class = "control-label" })
                @Html.Kendo().DateTimePickerFor(model => model.CommStartDate).HtmlAttributes(new {  @class = "form-control"})
                @Html.ValidationMessageFor(model => model.CommStartDate, "", new { @class = "text-danger" })
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.NewRegistrationNote, htmlAttributes: new { @class = "control-label" })
                @Html.EditorFor(model => model.NewRegistrationNote, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.NewRegistrationNote, "", new { @class = "text-danger" })
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.LicenseNumber, htmlAttributes: new { @class = "control-label" })
                @Html.EditorFor(model => model.LicenseNumber, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.LicenseNumber, "", new { @class = "text-danger" })
            </div>
        </div>
    </div>

     

    I've noticed that when I click the button to save the data I intend to Insert, both of the methods above in the controller are called. That surprised me. Why bother with two methods when both are called? Or, is there a way to make only one method is called depending on whether it's and Edit versus a Create?

    More importantly, when these methods are called, they get called for every record in the grid. I just want the UpdateAgency method called once by the record being edited. And the CreateAgency method called once when the user submits the form that pops up from the toolbar.

    Finally, and most important, I need to pass some values to the controller that are found in the data. I need to pass the AgencyID and AgentID to the controller when the CreateAgency method is called.

    Thanks for any help,

    Andy

     

  2. Stefan
    Admin
    Stefan avatar
    2835 posts

    Posted 09 Nov 2017 Link to this post

    Hello, Andrew,

    Thank you for the provided information.

    After inspecting the code, the dataSource has different methods for create and update and it should not call both actions. This can be observed in our demo:

    http://demos.telerik.com/aspnet-mvc/grid/editing-popup

    As this seems very strange behavior, it will be very helpful if a runnable example is provided, so we can inspect what is causing this.

    Also, an additional data can be sent to the Controller using the methods described in the following article:

    https://docs.telerik.com/aspnet-mvc/helpers/grid/faq#how-to-send-values-to-my-action-method-when-binding-the-grid

    If additional assistance is needed, I will be expecting the example and will gladly investigate.

    Regards,
    Stefan
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top