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

ForeignKey column not working in PopUp edit mode: doesn't show the correct item selected

3 Answers 625 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Stargazer
Top achievements
Rank 1
Stargazer asked on 26 Jul 2013, 03:18 PM
Hello! :)

I've searched for all over the place (understatement) for a solution to my case to no avail until now. First, I'll explain my scenario:
- I have an OpenAccess Model exposed as a WCF Data Service (oData v3);
- I have an Kendo MVC Application;
- I have a View with a grid, set for PopUp editing, AJAX Bound;
Before posting some code, let me explain my issue/difficulty. I have an entity with these properties:
 - TextoID
 - Titulo;
 - Corpo;
 - TipoTextoID;
 - TipoTexto;

There is a ForeignKey column set to the TipoTextoID property which get's correctly populated either in in-line or pop-up mode. But when it comes to changing data, it only works in-line mode. This is my issue I need it to work in a popup, since the "Corpo" property is bound to a KendoUI Editor.
When in the popup, it does not show the correct value on the dropdown. It shows always the first item on the dropdown.
Honestly I'm feeling stupid. I tried almost every sample, post, article I could find to no avail and I'm clueless.
I hope someone can help me on this. Thanks in advance to all!

So, here's the code.
The view:
01.@model IEnumerable<KendoMVC.CostSimulatorService.Texto>
02. 
03.@{
04.    ViewBag.Title = "Textos";
05.    Layout = "~/Views/Shared/_Layout.cshtml";
06.}
07. 
08.<h2>Textos</h2>
09. 
10.@(Html.Kendo().Grid(Model) // Bind the grid to the Model property of the view
11.      .Name("Grid")
12.      .Columns(columns =>
13.      {
14.          columns.Bound(p => p.Titulo);   //Create a column bound to the "ProductID" property
15.          columns.Bound(p => p.IsPrivado)
16.              .ClientTemplate("<input type='checkbox' #= IsPrivado ? checked='checked': '' # class='chkbx' />")
17.              .Width(170); //Create a column bound to the "ProductName" property
18.          columns.ForeignKey(p => p.TipoTextoID,
19.                                 (System.Collections.IEnumerable)ViewData["TiposTexto"],
20.                                 "TipoTextoID",
21.                                 "Designacao")
22.                            .Title("Tipo de conteúdo").Width(170);
23.          columns.Command(command =>
24.          {
25.              command.Edit();
26.              command.Destroy().Text("Remover");
27.          }).Width(200).Title("Acções");
28.      })
29.      .ToolBar(commands => commands.Create())
30.          .Editable(editable => editable.Mode(GridEditMode.PopUp)
31.              .TemplateName("Texto")
32.              .Window(builder => builder
33.                  .Width(800)
34.                  .Height(570)
35.                  .Modal(true)
36.                  .Resizable(c => c.Enabled(true))
37.                  .Animation(true)
38.                  .Title("Editar conteúdo")))
39.      .DataSource(dataSource => dataSource
40.            .Ajax() //specify server type
41.            .PageSize(20)
42.            .Events(events => events.Error("error_handler"))
43.            .Model(model =>
44.            {
45.                model.Id(texto => texto.TextoID); // Specify the property which is the unique identifier of the model
46.                model.Field(texto => texto.TextoID).Editable(false); // Make the ProductID property not editable
47.            })
48.            .Create(create => create.Action("CreateTexto", "Textos"))
49.            .Read(read => read.Action("ReadTextos", "Textos"))
50.            .Update(update => update.Action("UpdateTexto", "Textos"))
51.            .Destroy(destroy => destroy.Action("DestroyTexto", "Textos")))
52.     .Pageable() // Enable paging
53.     .Sortable() // Enable sorting
54.     .Selectable()
55.     .Filterable()
56.     .Scrollable()
57.         )
58. 
59.<script type="text/javascript">
60. 
61.    $(document).ready(function() {       
62.        $("form.k-edit-form").kendoValidator();
63.    });
64. 
65.    function error_handler(e) {
66.        if (e.errors) {
67.            var message = "Errors:\n";
68.            $.each(e.errors, function (key, value) {
69.                if ('errors' in value) {
70.                    $.each(value.errors, function () {
71.                        message += this + "\n";
72.                    });
73.                }
74.            });
75.            alert(message);
76.        }
77.    }
78.</script>
Next, then template:
01.@using System.Web.Mvc.Html;
02. 
03.@model KendoMVC.CostSimulatorService.Texto
04. 
05.@Html.HiddenFor(model => model.TextoID)
06.<div id="divWrapper" style="width:99%; float:left; height:520px; margin-left:2px;">
07.    <div>
08.        @Html.LabelFor(model => model.Titulo)
09.    </div>
10.    <div>
11.        @Html.TextBoxFor(model => model.Titulo, new { @class="k-textbox" , style = "width: 480px;" })
12.        @Html.ValidationMessageFor(model => model.Titulo)
13.    </div>
14.    <div>
15.        @Html.LabelFor(model => model.Corpo)
16.    </div>
17.    <div style="width:98%;">
18.        @(Html.Kendo().EditorFor(model => model.Corpo)
19.                      .HtmlAttributes(new { style = "width: 740px;height:350px" })
20.                      .ImageBrowser(imageBrowser => imageBrowser
21.                                                                  .Image("~/Content/Uploads/Images/{0}")
22.                                                                  .Read("Read", "Textos")
23.                                                                  .Create("Create", "Textos")
24.                                                                  .Destroy("Destroy", "Textos")
25.                                                                  .Upload("Upload", "Textos")
26.                                                                  .Thumbnail("Thumbnail", "Textos"))
27.                        .Messages(m => m.DialogCancel("Cancelar")
28.                        .DialogInsert("Inserir")
29.                        .ImageAltText("Texto alternativo"))
30.                                                        )
31.        @Html.ValidationMessageFor(model => model.Corpo)
32.    </div>
33.    <div>
34.        @Html.LabelFor(model => model.TipoTextoID)
35.    </div>
36.    <div>
37.        @Html.HiddenFor(model => model.TipoTextoID)
38.        @(Html.Kendo().DropDownListFor(model => model.TipoTextoID)
39.            .Name("TiposTexto")
40.            .DataTextField("Designacao")
41.            .DataValueField("TipoTextoID")
42.            .BindTo((System.Collections.IEnumerable)
43.           ViewData["TiposTexto"]))
44.    </div>
45.    <div style="float:left; width:155px;">
46.        @Html.LabelFor(model => model.IsPrivado)
47.    </div>
48.    <div style="float:left;">
49.        @Html.CheckBoxFor(model => model.IsPrivado)
50.        @Html.ValidationMessageFor(model => model.IsPrivado)
51.    </div>
52.</div>
The controller:
001.using System;
002.using System.Data.Common.CommandTrees.ExpressionBuilder;
003.using System.IO;
004.using System.Linq;
005.using System.Web;
006.using System.Web.Mvc;
007.using Kendo.Mvc.Extensions;
008.using Kendo.Mvc.UI;
009.using KendoMVC.CostSimulatorService;
010.using KendoMVC.ImageBrowser.Models;
011. 
012.namespace KendoMVC.Controllers
013.{
014.    public partial class TextosController : EditorImageBrowserController
015.    {
016.        #region Propriedades e Campos
017. 
018.        private const string ContentFolderRoot = "~/Content/";
019.        private const string PrettyName = "Images/";
020.        private static readonly string[] foldersToCopy = new[] { "~/Content/Uploads/Shared/" };
021. 
022.        #endregion
023. 
024.        #region CRUD
025. 
026.        #region ReadTextos
027. 
028.        public ActionResult ReadTextos([DataSourceRequest]DataSourceRequest request)
029.        {
030.            CostSimulatorModel modelo = new CostSimulatorModel(new Uri(@"http://localhost:53212/CostSimulatorModelService.svc/"));
031. 
032.            IQueryable<Texto> textos = modelo.Textos;
033.            DataSourceResult resultado = textos.ToDataSourceResult(request);
034.            ViewData["Textos"] = textos;
035.            return Json(resultado, JsonRequestBehavior.AllowGet);
036.        }
037. 
038.        #endregion
039. 
040.        #region CreateTexto
041. 
042.        [ValidateInput(false)]
043.        public ActionResult CreateTexto([DataSourceRequest]DataSourceRequest request, Texto texto)
044.        {
045.            if (ModelState.IsValid)
046.            {
047.                CostSimulatorModel modelo = new CostSimulatorModel(new Uri(@"http://localhost:53212/CostSimulatorModelService.svc/"));
048.                 
049.                // Create a new Product entity and set its properties from the posted ProductViewModel
050.                Texto entity = new Texto
051.                {
052.                    TextoID = texto.TextoID,
053.                    Titulo = texto.Titulo,
054.                    Corpo = texto.Corpo,
055.                    IsPrivado = texto.IsPrivado,
056.                    TipoTextoID = texto.TiposTexto != null ? texto.TiposTexto.TipoTextoID : texto.TipoTextoID,
057.                    TiposTexto = texto.TiposTexto
058.                };
059.                modelo.AddToTextos(entity);
060.                // Insert the entity in the database
061.                modelo.SaveChanges();
062.                // Get the ProductID generated by the database
063.                texto.TextoID = entity.TextoID;
064.                return Json(new[] { entity }.ToDataSourceResult(request, ModelState));
065.            }
066.            // Return the inserted product. The grid needs the generated ProductID. Also return any validation errors.
067.            return Json(new[] { texto }.ToDataSourceResult(request, ModelState));
068.        }
069. 
070.        #endregion
071. 
072.        #region UpdateTexto
073. 
074.        [ValidateInput(false)]
075.        public ActionResult UpdateTexto([DataSourceRequest]DataSourceRequest request, Texto texto)
076.        {
077.            if (ModelState.IsValid)
078.            {
079.                CostSimulatorModel modelo = new CostSimulatorModel(new Uri(@"http://localhost:53212/CostSimulatorModelService.svc/"));
080. 
081.                // Create a new Product entity and set its properties from the posted ProductViewModel
082.                var entity = new Texto
083.                {
084.                    TextoID = texto.TextoID,
085.                    Titulo = texto.Titulo,
086.                    Corpo = texto.Corpo,
087.                    IsPrivado = texto.IsPrivado,
088.                    TipoTextoID = texto.TiposTexto != null ? texto.TiposTexto.TipoTextoID : texto.TipoTextoID,
089.                    TiposTexto = texto.TiposTexto
090.                };
091.                // Attach the entity
092.                modelo.AttachTo("Textos", entity);
093.                modelo.UpdateObject(entity);
094.                // Update the entity in the database
095.                modelo.SaveChanges();
096.                return Json(new[] { entity }.ToDataSourceResult(request, ModelState));
097.            }
098.            // Return the updated product. Also return any validation errors.
099.            return Json(new[] { texto }.ToDataSourceResult(request, ModelState));
100.        }
101. 
102.        #endregion
103. 
104.        #region DestroyTexto
105.         
106.        public ActionResult DestroyTexto([DataSourceRequest]DataSourceRequest request, Texto texto)
107.        {
108.            if (ModelState.IsValid)
109.            {
110.                CostSimulatorModel modelo = new CostSimulatorModel(new Uri(@"http://localhost:53212/CostSimulatorModelService.svc/"));
111. 
112.                // Create a new Product entity and set its properties from the posted ProductViewModel
113.                var entity = new Texto
114.                {
115.                    TextoID = texto.TextoID
116.                };
117.                // Attach the entity
118.                modelo.AttachTo("Textos", entity);
119.                // Delete the entity
120.                modelo.DeleteObject(entity);
121.                 
122.                // Delete the entity in the database
123.                modelo.SaveChanges();
124.                return Json(new[] { entity }.ToDataSourceResult(request, ModelState));
125.            }
126.            // Return the removed product. Also return any validation errors.
127.            return Json(new[] { texto }.ToDataSourceResult(request, ModelState));
128.        }
129. 
130.        #endregion
131. 
132.        #endregion
133. 
134.        #region ImageBrowser Code
135. 
136.        /// <summary>
137.        /// Gets the base paths from which content will be served.
138.        /// </summary>
139.        public override string ContentPath
140.        {
141.            get
142.            {
143.                return CreateUserFolder();
144.            }
145.        }
146. 
147.        private string CreateUserFolder()
148.        {
149.            var virtualPath = Path.Combine(ContentFolderRoot, "Uploads", PrettyName);
150. 
151.            var path = Server.MapPath(virtualPath);
152.            if (!Directory.Exists(path))
153.            {
154.                Directory.CreateDirectory(path);
155.                foreach (var sourceFolder in foldersToCopy)
156.                {
157.                    CopyFolder(Server.MapPath(sourceFolder), path);
158.                }
159.            }
160.            return virtualPath;
161.        }
162. 
163.        private void CopyFolder(string source, string destination)
164.        {
165.            if (!Directory.Exists(destination))
166.            {
167.                Directory.CreateDirectory(destination);
168.            }
169. 
170.            foreach (var file in Directory.EnumerateFiles(source))
171.            {
172.                var dest = Path.Combine(destination, Path.GetFileName(file));
173.                System.IO.File.Copy(file, dest);
174.            }
175. 
176.            foreach (var folder in Directory.EnumerateDirectories(source))
177.            {
178.                var dest = Path.Combine(destination, Path.GetFileName(folder));
179.                CopyFolder(folder, dest);
180.            }
181.        }
182. 
183.        #endregion
184.    }
185.}
This is a copy of my StackOverflow initial post (which got 0 replies in 3 days, so I had to come here :) )

Cheers and thanks in advance!

3 Answers, 1 is accepted

Sort by
0
Accepted
Vladimir Iliev
Telerik team
answered on 30 Jul 2013, 02:23 PM
Hi Nuno,

 
I would suggest to use the default editor template for the ForeignKeyColumn ("GridForeignKey.cshtml") as an editor for the "TipoTextoID" field in the following way:

  •  Set custom editor template for the model property using UIHint attribute:
    public class Order
    {
        public int OrderID { get; set; }
        public DateTime OrderDate { get; set; }
        public string OrderDescription { get; set; }
        //set the property to use the default ForeignKeyColumn editor
        [UIHint("GridForeignKey")]
        public int EmployeeID { get; set; }
    }
  • In the custom PopUp editor template define only EditorFor:  
    @(Html.EditorFor(m => m.EmployeeID))     

 Kind Regards,
Vladimir Iliev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Stargazer
Top achievements
Rank 1
answered on 30 Jul 2013, 02:36 PM
Hello Vladimir!

Thanks for the reply. I'll try that (I must confess I do not recall if I tried that already or not) and then let you know if it worked.

[EDIT] It's working flawlessly now. Thanks, Vladimir!

All the best,
Nuno
0
Manish
Top achievements
Rank 1
answered on 30 Dec 2013, 07:13 PM
Hello
what model should i set on custom template?

I am getting errors:

Compiler Error Message: CS1963: An expression tree may not contain a dynamic operation

or

Exception Details: System.InvalidOperationException:
The model item passed into the dictionary is of type 'System.Int32',
but this dictionary requires a model item of type
'SystemDashboard.ProviderMaintenanceSMS'.

Thanks!

Tags
Grid
Asked by
Stargazer
Top achievements
Rank 1
Answers by
Vladimir Iliev
Telerik team
Stargazer
Top achievements
Rank 1
Manish
Top achievements
Rank 1
Share this question
or