Uncaught ReferenceError when trying to create new record

4 posts, 0 answers
  1. Nicklas
    Nicklas avatar
    45 posts
    Member since:
    Oct 2012

    Posted 21 May 2014 Link to this post

    Hi,

    I'm working on a grid (somewhat similar, but also a bit different in terms of underlying model) again. I'm having issues with creating a new record.

    Whenever I press the "Add new record" button, nothing happens and the browser console says the following:
    Uncaught ReferenceError: CustomerContract is not defined.

    Here's my grid and relevant templates in the razor view:
    <script type="text/kendo" id="customerTemplate">
        #if(data != null){#
        #:data.Name#
        #}#
    </script>
     
    <script type="text/javascript">
        var customerTemplate = kendo.template($("#customerTemplate").html(), { useWithBlock: false });
    </script>
     
    <div class="container">
        <div class="row">
            <div class="col-md-12 sl-table">
                @(Html.Kendo().Grid<ProjectModel>()
                      .Name("grid")
                      .Columns(columns =>
                      {
                          columns.Bound(p => p.Name);
                          columns.Bound(p => p.CustomerContract).ClientTemplate("#=customerTemplate(CustomerContract)#");
                          columns.Command(command =>
                          {
                              command.Edit();
                              command.Destroy();
                          }).Width(180);
                      })
                      .ToolBar(toolbar => toolbar.Create())
                      .Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("ProjectPopUpTemplate"))
                      .Pageable()
                      .Sortable()
                      .Scrollable()
                      .HtmlAttributes(new {style = "height:500px;"})
                      .DataSource(dataSource => dataSource
                          .Ajax()
                          .PageSize(10)
                          .Events(events => events.Error("error_handler"))
                          .Model(model => model.Id(p => p.Id))
                          .Create(update => update.Action("EditingPopup_Create", "ProjectManagement"))
                          .Read(read => read.Action("EditingPopup_Read", "ProjectManagement"))
                          .Update(update => update.Action("EditingPopup_Update", "ProjectManagement"))
                          .Destroy(destroy => destroy.Action("EditingPopup_Destroy", "ProjectManagement"))
                      )
                      )
            </div>
        </div>
    </div>
    Now, the grid populates fine, and the edit button works. It's only an issue when pressing the "Add new record" button.
    Here's how my controller looks (removed the update / destroy actions):
    public class ProjectManagementController : BaseController
        {
            static readonly ILog Log = LogManager.GetLogger("ProjectManagementController.class");
            private static readonly List<Customer> CustomerList = new List<Customer>();
            public ProjectServiceClient ProjectService { get; set; }
            public CustomerServiceClient CustomerService { get; set; }
            public ProjectModel Model { get; set; }
     
            public ProjectManagementController()
            {
                try
                {
                    ProjectService = new ProjectServiceClient();
                    CustomerService = new CustomerServiceClient();
                }
                catch (Exception e)
                {
                    Log.Error(e);
                    throw;
                }
            }
     
            // GET: ProjectManagement
            public ActionResult Projects()
            {
                List<CustomerContract> customers = CustomerService.GetCustomers().ToList();
                Model = new ProjectModel();
                foreach (var customer in customers)
                {
                    CustomerList.Add(new Customer
                    {
                        Name = customer.Name,
                        Id = customer.Id
                    });
                }
     
                ViewData["Customers"] = GetAll();
     
                return View(Model);
            }
     
            public ActionResult EditingPopup_Read([DataSourceRequest] DataSourceRequest request)
            {
                ProjectContract[] list = ProjectService.GetProjects();
                return Json(list.ToDataSourceResult(request));
            }
     
            [AcceptVerbs(HttpVerbs.Post)]
            public ActionResult EditingPopup_Create([DataSourceRequest] DataSourceRequest request, ProjectModel project)
            {
                if (project != null && ModelState.IsValid)
                {
                    CustomerContract customer = CustomerService.GetCustomer(project.CustomerContract.Id);
                    var newProject = ProjectService.InsertProject(new ProjectContract
                    {
                        CustomerContract = customer,
                        Name = project.Name,
                        Id = project.Id
                    });
     
                    ProjectService.UpdateProject(newProject);
                }
     
                return Json(new[] { project }.ToDataSourceResult(request, ModelState));
            }
        }
    The service call in the read method returns a list of ProjectContracts. A ProjectContract consists of a few properties of type string and another property of type CustomerContract (which holds its own string properties). Could this nested contract possibly be the problem?

    Finally, here's my model which the grid is based on:   
    public class ProjectModel
    {
        private ProjectContract _projectContract;
     
        public ProjectModel(ProjectContract projectContract)
        {
            ProjectContract = projectContract;
        }
     
        public ProjectModel()
        {
        }
     
        public CustomerServiceClient CustomerService { get; set; }
     
        private ProjectContract ProjectContract
        {
            get
            {
                if (_projectContract == null)
                {
                    _projectContract = new ProjectContract();
                }
     
                return _projectContract;
            }
            set { _projectContract = value; }
        }
     
        [Display(Name = "Customer")]
        public CustomerContract CustomerContract
        {
            get
            {
                if (ProjectContract.CustomerContract == null)
                {
                    return new CustomerContract();
                }
     
                return ProjectContract.CustomerContract;
            }
            set { ProjectContract.CustomerContract = value; }
        }
     
        [Display(Name = "Customers")]
        public List<Customer> Customers { get; set; }
     
        [ScaffoldColumn(false)]
        public int Id
        {
            get { return ProjectContract.Id; }
            set { ProjectContract.Id = value; }
        }
     
        [Display(Name = "Project Name")]
        public string Name
        {
            get { return ProjectContract.Name; }
            set { ProjectContract.Name = value; }
        }
    }

    How can I go about solving this?
  2. Nicklas
    Nicklas avatar
    45 posts
    Member since:
    Oct 2012

    Posted 22 May 2014 in reply to Nicklas Link to this post

    Problem solved. :) 
    @(Html.Kendo().Grid<ProjectModel>()
          .Name("grid")
          .Columns(columns =>
          {
              columns.Bound(p => p.Name);
              columns.Bound(p => p.CustomerContract).ClientTemplate("#=customerTemplate(CustomerContract)#");
              columns.Command(command =>
              {
                  command.Edit();
                  command.Destroy();
              }).Width(180);
          })
          .ToolBar(toolbar => toolbar.Create())
          .Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("ProjectPopUpTemplate"))
          .Pageable()
          .Sortable()
          .Scrollable()
          .HtmlAttributes(new {style = "height:500px;"})
          .DataSource(dataSource => dataSource
              .Ajax()
              .PageSize(10)
              .Events(events => events.Error("error_handler"))
              .Model(model =>
              {
                  model.Id(p => p.Id);
                  model.Field(p => p.CustomerContract).DefaultValue(new CustomerContract());
              } )
              .Create(update => update.Action("EditingPopup_Create", "ProjectManagement"))
              .Read(read => read.Action("EditingPopup_Read", "ProjectManagement"))
              .Update(update => update.Action("EditingPopup_Update", "ProjectManagement"))
              .Destroy(destroy => destroy.Action("EditingPopup_Destroy", "ProjectManagement"))
          )
          )
    @model ProjectModel
    <div class="editor-label">
        @(Html.LabelFor(model => model.Name))
    </div>
    <div class="editor-field">
        @(Html.TextBoxFor(model => model.Name))
    </div>
    <div class="editor-label">
        @Html.LabelFor(model => model.CustomerContract)
    </div>
    <div data-container-for="CustomerContract" class="editor-field">
        @(Html.Kendo().DropDownListFor(m => m.CustomerContract)
              .DataTextField("Name")
              .DataValueField("Id")
              .DataSource(d => d.Read("CustomerContract_Read", "ProjectManagement"))
              )
    </div>
    public class ProjectModel
    {
        private ProjectContract _projectContract;
     
        public ProjectModel(ProjectContract projectContract)
        {
            ProjectContract = projectContract;
        }
     
        public ProjectModel()
        {
             
        }
     
        public CustomerServiceClient CustomerService { get; set; }
     
        private ProjectContract ProjectContract
        {
            get
            {
                if (_projectContract == null)
                {
                    _projectContract = new ProjectContract();
                }
     
                return _projectContract;
            }
            set { _projectContract = value; }
        }
     
        [Display(Name = "Customer")]
        public CustomerContract CustomerContract
        {
            get
            {
                if (ProjectContract.CustomerContract == null)
                {
                    return new CustomerContract();
                }
     
                return ProjectContract.CustomerContract;
            }
            set { ProjectContract.CustomerContract = value; }
        }
     
        [ScaffoldColumn(false)]
        public int Id
        {
            get { return ProjectContract.Id; }
            set { ProjectContract.Id = value; }
        }
     
        [Display(Name = "Project Name")]
        public string Name
        {
            get { return ProjectContract.Name; }
            set { ProjectContract.Name = value; }
        }
    }
  3. Kryszal
    Kryszal avatar
    5 posts
    Member since:
    Aug 2015

    Posted 14 Aug 2015 Link to this post

    So I see that it is needed to define a default value in a grid helper for the column which is bound to a nested property.
  4. Boyan Dimitrov
    Admin
    Boyan Dimitrov avatar
    2048 posts

    Posted 18 Aug 2015 Link to this post

    Hello Kryszal,

     

    When a new item is created the values of the model are set to its default settings. 

    Default settings depend on the type of the field. Default for "string" is "", for "number" is 0 and for "date" is new Date() (today). 

     

    Given this for a complex/nested property a default value should be explicitly set. 

     

    Regards,
    Boyan Dimitrov
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top