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

Uncaught ReferenceError when trying to create new record

3 Answers 762 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Nicklas
Top achievements
Rank 1
Nicklas asked on 21 May 2014, 10:36 AM
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?

3 Answers, 1 is accepted

Sort by
0
Nicklas
Top achievements
Rank 1
answered on 22 May 2014, 10:25 AM
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; }
    }
}
0
Kryszal
Top achievements
Rank 1
answered on 14 Aug 2015, 01:14 PM
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.
0
Boyan Dimitrov
Telerik team
answered on 18 Aug 2015, 09:00 AM

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
Tags
Grid
Asked by
Nicklas
Top achievements
Rank 1
Answers by
Nicklas
Top achievements
Rank 1
Kryszal
Top achievements
Rank 1
Boyan Dimitrov
Telerik team
Share this question
or