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

[Solved] Passing Model to Edit Template

13 Answers 390 Views
Grid
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Frank Michael
Top achievements
Rank 1
Frank Michael asked on 17 May 2010, 03:06 PM
I have a Grid with editing and an edit template
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<WorkitemGridRow>" %> 
<%= Html.DropDownListFor<WorkitemGridRow, string>
        w => w.Status, 
        new CodeProvider<WorkitemStatusCode>().selectList.Select(entry=> new SelectListItem { 
                Value = entry.Value, 
                Text = entry.Text, 
                Selected = entry.Value == Model.Status 
        })) 
%> 

What I want to do is to set the dropdown List Value to the current value, that the table row has. But when I access the model, then the Model is Null.
I think it must be passed to the Template by Telerik Grid, not by me. Am I wrong?
And is there a way to influence the sort order of the values?

13 Answers, 1 is accepted

Sort by
0
Atanas Korchev
Telerik team
answered on 17 May 2010, 03:18 PM
Hi Frank Michael ,

We need more details about your implementation:
  1. Are you using server or client binding. Server code in editor templates will be executed only if you are using server binding
  2. How does the bound object look like?
  3. Are you aware that templates are not implemented for nested complex objects? Fortunately a workaround exists and is described in the blog post and implemented in this demo. Check Employee.ascx in the examples source code.
  4. Is this the editor template for the whole model or just a property? The grid currently supports only per property templates (e.g. Date.asx, Number.ascx).

The grid passes the model always during server binding and editing. If you are using ajax the grid is passing a dummy (empty) model just to output the editor templates as HTML. They are later used by the client-side editing implementation and populated with data.

Regards,
Atanas Korchev
the Telerik team

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 Public Issue Tracking system and vote to affect the priority of the items.
0
Frank Michael
Top achievements
Rank 1
answered on 17 May 2010, 03:26 PM
I am using Ajax Editing / Client Binding.
The bound object is this:
 public class Workitem : TableServiceEntity, IComparable<Workitem>, IPatternModel, IFastSearchable<Workitem> 
    { 
        // ToDo: diese beiden ausmustern 
        internal const string cAttachmentBlobContainer = "attachments"
        public const string cObjectName = "Workitem"
     
        [Required] 
        public virtual String Title { getset;} 
 
        [PatternListExclude] 
        [PatternSearchExclude] 
        public String SuperWorkitem { getset; }  
 
        [PatternListExclude] 
        public virtual String Description { getset;} 
 
        public bool Urgent { getset; } 
 
        public bool Important { getset; } 
 
        [PatternListExclude] //DoTo: entfernen 
        [PatternSearchExclude] // ToDo: Entfernen 
        public bool TopLevel { get {return String.IsNullOrEmpty(SuperWorkitem);} set{} } 
 
        [UIHint("WorkitemStatusCode"), Required] 
        public String Status { getset; } 
 
        [PatternSearchExclude] 
        public String Category { getset; } 
 
        [PatternListExclude] 
        [PatternSearchExclude] 
        public String Sprint { getset; } 
 
        [PatternSearchExclude] 
        public double RemainingDays { getset; } 
 
        [PatternSearchExclude] 
        public double RemainingHours { getset; } 
 
        [PatternListExclude] 
        [PatternSearchExclude] 
        public double FreeRemainingDays { getset; } 
 
        [PatternListExclude] 
        [PatternSearchExclude] 
        public double FreeRemainingHours { getset; } 
 
        [PatternListExclude] 
        [PatternSearchExclude] 
        public String CreatedBy { getset; } 
         
        [PatternListExclude] 
        [PatternSearchExclude] 
        public DateTime CreatedAt { getset; } 
         
        [PatternListExclude] 
        [PatternSearchExclude] 
        public String ChangedBy { getset; } 
         
        [PatternListExclude] 
        [PatternSearchExclude] 
        public DateTime ChangedAt { getset; } 
... and this:

public class WorkitemGridRow : Workitem 
    { 
        [ReadOnly(true)] 
        public String SprintTitle { getset; } 
 
        [ReadOnly(true)] 
        public double effort { getset; } 
 
        [ReadOnly(true)] 
        public string chartlet 
        { 
            get 
            { 
                String result = "http://chart.apis.google.com/chart?chs=50x50&cht=p"
 
                double roweffort = RemainingDays * 8 + RemainingHours; 
 
                double rowpercentage = 0; 
 
                if (effort != 0) 
                    rowpercentage = Math.Ceiling(roweffort * 100 / effort); 
                else 
                    rowpercentage = 0; 
 
                double restpercentage = 100 - rowpercentage; 
 
                result += "&chd=t:"
                result += rowpercentage.ToString(); 
                result += ","
                result += restpercentage.ToString(); 
 
                return result; 
 
            } 
 
            set { } 
        } 
    } 

I already used employee.ascx as a reference.
The field is only a dropdown - an IEnumerable<System.Web.Mvc.SelectListItem>
How can I make the client side implementation select the current value of the field as preset value?
0
Frank Michael
Top achievements
Rank 1
answered on 17 May 2010, 03:51 PM
I am a little bit confused.
In your example
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Employee>" %> 
<%= Html.DropDownList(null, new SelectList((IEnumerable) ViewData["employees"], "Id", "Name", Model.EmployeeID.ToString()))%> 
there you are also accessing the Model.
Is it because the example is only for server binding?
0
Frank Michael
Top achievements
Rank 1
answered on 17 May 2010, 04:11 PM
Tell me, is the following sentence true?

"If an editor template field for a grid needs to make use of a drowdown list box, then either the list items must be known at compile time or it is necessary to use server binding."
0
Frank Michael
Top achievements
Rank 1
answered on 17 May 2010, 05:41 PM
I tried this solution:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<WorkitemGridPattern>" %> 
<select name="Status"
    <% foreach (var entry in Model.statusSelection) {%> 
          <option value="<%=entry.Value %>" <#= <%=entry.Value %> == Status ? selected : '' #> ><%=entry.Text %></option
    <% } %> 
</select> 

and I activated Server Binding, hoping that the model is then passed to the edit template. But not help.
0
Frank Michael
Top achievements
Rank 1
answered on 17 May 2010, 05:49 PM
And if I do this, then I do not have success either.
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<WorkitemGridRow>" %> 
Because then I have no access to statusSelection that I fill in the server.
So this seems like a contradiction.
It is completely unclear to me if I should do the template for the model or for the table.
Naturally I would say it should be for the table.
But then I must include the selection list in each row. Hrrrm - would make some sense, if the model is filled at all.
But then I believe I can render a different selection for any row on the server anyway, then I do not need Client template.
But what if I changed the status on the client? How to make sure, that then after the change also the current value is selected, because then I am not accessing the server again.

It is IMPORTANT, because, what if the current value is not selected. If you go to edit mode, and don't change the field it has a different value later. This is really bad usability.
0
Accepted
Atanas Korchev
Telerik team
answered on 17 May 2010, 06:43 PM
Hi Frank Michael ,

Our example (Employee.ascx) is using server binding. You must use server binding too if you need to set the values.

However you seem to be creating an edit template for the whole type (WorkItemGridRow). This is currently not supported as the grid only allows inline editing. It needs an editor for every column.

You can create template only for a model property (statusselection in your case).

In our example we have implemented the template for the Employee property of the EditableOrder object:
[UIHint("Employee"), Required]
public Employee Employee { get; set; }

In the Employee.ascx example however Model is of type Employee and not Order (the type bound to the grid). Also make sure you have decorated the type of which the property is with the TypeConverter attribute as we have done:
    [TypeConverter(typeof(EmployeeConverter))]
    public partial class Employee
    {
    }

    public class EmployeeConverter : TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            return (sourceType == typeof(string)) ? true : base.CanConvertFrom(context, sourceType);
        }
    }

Unfortunately I cannot help further without seeing more of your code. You don't need to send the entire project. A simple bound grid with dummy values will help us understand the obstacles you have hit.

Regards,
Atanas Korchev
the Telerik team

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 Public Issue Tracking system and vote to affect the priority of the items.
0
Frank Michael
Top achievements
Rank 1
answered on 17 May 2010, 10:06 PM
Ok, let me most clearly state my problem:

HOW do I preselect the current value of a row field in a dropdown list in a scenario where I use client editing?

Your example does not have such a thing.

For clarification of the problem see this code, that I tried to make up:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<String>" %> 
<select name="WorkitemStatusCode"
    <% foreach (var entry in new CodeProvider<WorkitemStatusCode>().selectList()) 
       {%> 
          <option value="<%=entry.Value %>" <#= Status == <%=entry.Value%>  ?  selected #> ><%=entry.Text %></option
    <% } %> 
</select> 

The rendered html is this:

<select name="WorkitemStatusCode" class="valid"
     
          <option value="Approved">&lt;#= Status == Approved  ?  selected #&gt; &gt;Approved</option> 
     
          <option value="Finished">&lt;#= Status == Finished  ?  selected #&gt; &gt;Finished</option> 
     
          <option value="InApproval">&lt;#= Status == InApproval  ?  selected #&gt; &gt;In Approval</option> 
     
          <option value="Open">&lt;#= Status == Open  ?  selected #&gt; &gt;Open</option> 
     
          <option value="Planned">&lt;#= Status == Planned  ?  selected #&gt; &gt;Planned</option> 
     
          <option value="Postponed">&lt;#= Status == Postponed  ?  selected #&gt; &gt;Postponed</option> 
     
          <option value="Rejected">&lt;#= Status == Rejected  ?  selected #&gt; &gt;Rejected</option> 
     
          <option value="Started">&lt;#= Status == Started  ?  selected #&gt; &gt;Started</option> 
     
          <option value="Withdrawn">&lt;#= Status == Withdrawn  ?  selected #&gt; &gt;Withdrawn</option> 
     
</select> 

This is obviously not what I wanted. See also screenshots.
0
Frank Michael
Top achievements
Rank 1
answered on 17 May 2010, 11:17 PM
Ok - I have become very simple again and very close to the example.
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<String>" %> 
<%= Html.DropDownList(null, new SelectList(new CodeProvider<WorkitemStatusCode>().codeTextList, "key", "text", Model))%> 
works now and preselects the current value.
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %> 
<%= Html.DropDownList(null, new SelectList((IEnumerable<Sprint>)ViewData["sprints"], "RowKey", "Title", Model), "<--none-->")%> 
Works as well, but the current value is not preselected. Instead "<--none-->" is preselected.
I must admit in the upper example, the value of the field is equal to the value of the dropdown and to the text of the dropdown.
In the second example the value of the field is a readable short text, as well as the text of the dropdown, while the value of the dropdown is a guid. Maybe that is the problem.
0
Frank Michael
Top achievements
Rank 1
answered on 17 May 2010, 11:26 PM
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %> 
<%= Html.DropDownList(null, new SelectList((IEnumerable<Sprint>)ViewData["sprints"], "RowKey", "Title",  
        ((IEnumerable<Sprint>)ViewData["sprints"]).FirstOrDefault(s=>s.Title == Model)!=null? 
            ((IEnumerable<Sprint>)ViewData["sprints"]).First(s => s.Title == Model).RowKey 
            :String.Empty),  
        "<--none-->") 
%> 
Does not help either.
I do not see a difference between WorkitemStatusCode and SprintDropDown. Other than the labelOption "<--none-->"
0
Frank Michael
Top achievements
Rank 1
answered on 17 May 2010, 11:32 PM
Yes, indeed, if I leave the labelOption out, then it works.
But I need the lable option. But this is a new thread. I'll open a new thread.
Thanks for the example.
0
Ammar
Top achievements
Rank 1
answered on 31 Aug 2011, 03:43 PM
Hi Frank,

I am facing the same problem. Were you able to resolve the issue. If yes, can you please let me know as well how it was done. I am using Ajax binding.

Thanks,
Ammar
0
Frank Michael
Top achievements
Rank 1
answered on 31 Aug 2011, 04:08 PM
Sure.

At the grid:

 .ClientEvents(events => events.OnEdit(onEditEvent))

In JavaScript:

function onConfigureSprintSelection() {
    // find the dropdown first
    var $dropdown = $('select[name$="SprintModel"]');
    // find the table row (tr) which is being edited
    var $tr = $dropdown.closest('tr:has(form)');
    // get the grid client object
    var grid = $tr.closest('.t-grid').data('tGrid');
    // get the data item bound to this table row
    var dataItem = grid.dataItem($tr);
    // set the value of the dropdown to select the proper item
    var value = dataItem.SprintModel ? dataItem.SprintModel.RowKey : '';
    $dropdown.val(value);
}

Good Luck!
Tags
Grid
Asked by
Frank Michael
Top achievements
Rank 1
Answers by
Atanas Korchev
Telerik team
Frank Michael
Top achievements
Rank 1
Ammar
Top achievements
Rank 1
Share this question
or