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

[Solved] EditorTemplates and hidden form field

6 Answers 152 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.
Stefan
Top achievements
Rank 1
Stefan asked on 02 Aug 2011, 11:47 AM
Hello!
Using a EditorTemplate in concert with the Grid made me run into trouble.

The template:
@model Sardegna.Ali.WebUI.Models.CostCategoryViewModel
 
@Html.ValidationSummary(true, Resources.ErrorMessages.ErrorsOccured)
 
<fieldset>
    <legend>Kostenkategorie</legend>
         
    @Html.HiddenFor(model => model.Id)
    @Html.HiddenFor(model => model.Version)
         
    <div class="editor-label">
        @Html.LabelFor(model => model.Name)
    </div>
    (...)
</fieldset>

Simple enough. Essentially, a stripped down version of what MVC scaffolds for you.

 But wait, this gets generated:
<fieldset>
    <legend>Kostenkategorie</legend>
         
    <input data-val="true" data-val-number="The field Id must be a number." data-val-required="Das Feld &quot;Id&quot; ist erforderlich." id="Id" name="Id" type="hidden" value="3">
    <input id="Version" name="Version" type="hidden" value="AAAAAAAAAL4=">
         
    <div class="editor-label">
        <label for="Name">Bezeichnung</label>
    </div>
   (...)
</fieldset>
 
<input name="Id" type="hidden" value="3">
<button class="t-button t-button-icon t-grid-update" type="submit"><span class="t-icon t-update"></span></button>
<a class="t-button t-button-icon t-grid-cancel" href="/ALI/CostCategory"><span class="t-icon t-cancel"></span></a></div>

The thing gets wrapped into a form-tag and some buttons are appended too, that's ok and necessary and I understand that, but woah, why is there suddenly another Input-Tag for the Id field? Of course this will blow up in your face, since there are now two fields with the same name, which both can cause problems on the client and server-side.

Looks like the Grid appends a hidden field for each DataKey, so I guess this is intended behaviour, and even makes sense, somewhat.

My complaint with that is, that you have to remove your own HiddenFor, so it doesn't conflict with the one generated by the Grid, which reduces reusabilty of the template, since without an Id it's pretty much useless everywhere else. Couldn't you check if there already lingers a field for the DataKey around somewhere and then don't append yours? Or is there any other way to turn off this behaviour?

6 Answers, 1 is accepted

Sort by
0
Atanas Korchev
Telerik team
answered on 02 Aug 2011, 01:41 PM
Hi Stefan,

The grid indeed generates a hidden field for every DataKey because it is needed to identify the record during updating. This behavior cannot be stopped if you are using the built-in editing form otherwise editing won't work at all.

However if you are using a custom  editor form those fields should not be generated at all. I am sending a sample project which shows that.

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
Stefan
Top achievements
Rank 1
answered on 02 Aug 2011, 02:20 PM
I tested your example and it works as you said, but in my case, for whatever reason, it insists on outputting the input field after the fieldset. I can't seem to locate what I'm doing wrong.

Index.cshtml
@using Sardegna.Ali.WebUI.Models
@model IEnumerable<ArticleViewModel>
 
@(Html.Telerik().Grid(Model).Name("article-grid")
    .DataKeys(keys => keys.Add(m => m.Id))
    .DataBinding(binding => binding.Server().Select("Index", "Article").Insert("Create", "Article").Update("Edit", "Article").Delete("Delete", "Article"))
    .ToolBar(toolbar => toolbar.Insert().ButtonType(GridButtonType.ImageAndText))
    .Columns(column =>
    {
        column.Command(m => m.Edit().ButtonType(GridButtonType.Image)).Width(40);
        column.Bound(m => m.Name).Width(300);
        column.Bound(m => m.CostElementCostCategoryShortName).Width(200);
        column.Bound(m => m.CostElementShortName).Width(200);
        column.Bound(m => m.UnitPrice).Width(150);
        column.Command(m => m.Delete().ButtonType(GridButtonType.Image));
    })
    .Editable(edit => edit.Mode(GridEditMode.PopUp).Window(win => win.Width(500)))
    .Sortable()
    .Filterable()
    .Pageable())

ArticleViewModel.cs (Already tried removing ScaffoldColumn, using ReadOnly or nothing)
public class ArticleViewModel
{
    [ScaffoldColumn(false)]
    public int Id { get; set; }
 
    [Required, StringLength(100, MinimumLength = 3)]
    [Display(Name = "Bezeichnung")]
    public string Name { get; set; }
 
    [UIHint("CostElementId")]
    [Display(Name = "Kostenart")]
    public int CostElementId { get; set; }
 
    [ReadOnly(true)]
    [Display(Name = "Kostenart")]
    public string CostElementShortName { get; set; }
 
    [ReadOnly(true)]
    [Display(Name = "Kategorie")]
    public string CostElementCostCategoryShortName { get; set; }
 
    [DataType(DataType.Currency)]
    [Display(Name = "Einzelpreis")]
    public decimal? UnitPrice { get; set; }
 
    public byte[] Version { get; set; }
}

Action
public ActionResult Index()
{
    return View("Index", Mapper.Map<IEnumerable<Article>, IEnumerable<ArticleViewModel>>(_service.List()));
}

As far as I can tell, there is almost no difference, except I'm using server-binding and razor. Maybe I'm just blind to something obvious...
0
Accepted
Atanas Korchev
Telerik team
answered on 03 Aug 2011, 08:19 AM
Hi Stefan,

 You are right. The hidden is automatically generated during server editing as it should work even if JavaScript is disabled. Unfortunately we cannot detect if a custom editor template is being used. We just call Html.EditorForModel and use the returned html. Detection for duplicate html elements would require scanning the result returned by Html.EditorForModel which is error prone as quite a lot of things qualify as duplicate e.g.:

<input type="hidden" id="CustomerID" name="CustomerID" value="AFLKI" />
<input id="CustomerID" name="CustomerID" value="AFLKI" type="hidden"  />
<input name="CustomerID" id="CustomerID"  value="AFLKI" type="hidden"  />
...

Here are the possible workarounds:
- use ajax editing
- avoid adding the hidden field in your editor template
- use a different property as a grid data key ( a hidden will still be generated for that property)

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
Stefan
Top achievements
Rank 1
answered on 03 Aug 2011, 11:21 AM
I understand the part about detecting hidden fields, but you could add an additional Method to the DataKey-Configuration, with the current behaviour as default. .NoInput(true) or something. 
0
Atanas Korchev
Telerik team
answered on 03 Aug 2011, 11:52 AM
Hi Stefan,

 This indeed may work. Unfortunately I cannot commit if we will implement that in the near future (e.g. for the next official release). I recommend you use some of the recommended workarounds.

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
Stefan
Top achievements
Rank 1
answered on 03 Aug 2011, 11:54 AM
I've already gone down the route of removing my HiddenFor-Fields, so I'm gonna mark that as an answer.
Tags
Grid
Asked by
Stefan
Top achievements
Rank 1
Answers by
Atanas Korchev
Telerik team
Stefan
Top achievements
Rank 1
Share this question
or