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

Model property not set when bound to object

14 Answers 788 Views
ComboBox
This is a migrated thread and some comments may be shown as answers.
Bill Wingate
Top achievements
Rank 1
Bill Wingate asked on 03 Mar 2016, 12:12 AM

I have these model classes:

public class Part
{
    public Guid Id { get; set; }
    string Name { get; set; }
    public Part()
    {
    }
}
 
public class DetailItem
{
    public Guid Id { get; set; }
    public Part Part { get; set; }
 
    public DetailItem()
    {
    }
}

In my View, the model is the DetailItem. I am trying to use a ComboBox to select the Part for the DetailItem:

 

@(Html.Kendo().ComboBoxFor(model => model.Part)
    .DataValueField("Id")
    .DataTextField("Name")
    .Filter(FilterType.Contains)
    .DataSource(source =>
    {
        source.Read(read =>
        {
            read.Action("GetParts", "RefData");
        })
 
        .ServerFiltering(true);
    }
    )
)

When I save the page, the DetailItem.Part never gets set from the ComboBox. How do I make this work?

14 Answers, 1 is accepted

Sort by
0
Daniel
Telerik team
answered on 07 Mar 2016, 06:37 AM
Hello,

Is the combobox posted with a form? If yes, then you should bind the combobox to the Part.Id property:
Html.Kendo().ComboBoxFor(model => model.Part.Id)


Regards,
Daniel
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
0
Bill Wingate
Top achievements
Rank 1
answered on 07 Mar 2016, 07:11 PM

Thanks--I will try that.

How do I handle the case where the user enters a value that's not in the list in this case? How does the new value get passed back?

0
Daniel
Telerik team
answered on 09 Mar 2016, 11:39 AM
Hello again,

The custom value will be sent to the server but in most cases it will not be bound by the model binder. If custom values should be allowed then you could retrieve it from the ModelState or from the request data:
if (ModelState["Part.Id"].Errors.Any())
{
    var customValue = ModelState["Part.Id"].Value.AttemptedValue;
    ModelState.Remove("Part.Id");
    AddCustomValue(customValue);
}
 

Regards,
Daniel
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
0
Bill Wingate
Top achievements
Rank 1
answered on 10 Mar 2016, 03:03 PM

Binding to model.Part.Id worked for the ComboBox. Maybe this should be a new thread, but the next problem is that I have the ComboBox in a Grid.

To get the grid to show the part name instead of part ID when the cell isn't in edit mode, I have to have a ClientTemplate:

columns.Bound(p => p.Part.Id).EditorTemplateName("PartComboBox").ClientTemplate("#= Part.Name #");

That works until I enter a new custom value in the ComboBox. The ComboBox shows the value, but once I leave Edit mode for the cell, the grid shows "undefined" for the value. How do I get it showing the new value?

0
Daniel
Telerik team
answered on 14 Mar 2016, 08:23 AM
Hello,

If the same editor is used for a grid then I can suggest either to use a ForeignKey column for the Part.Id field or bind the column to the object and explicitly specify the binding in the editor via the HtmlAttributes method:
columns.Bound(p => p.Part)
Html.Kendo().ComboBoxFor(model => model.Part.Id)
    .HtmlAttributes(new { data_bind = "value:Part"})
    ...
This way the Id field will be posted correctly with the form but the object will be bound when using the editor for the grid. Using a separate editor for the grid is another option.


Regards,
Daniel
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
0
Bill Wingate
Top achievements
Rank 1
answered on 14 Mar 2016, 12:43 PM

I wasn't able to successfully apply either of those approaches in my scenario.

I have another class called "Assembly" that has a collection of Parts. On the edit page for an Assembly I have a grid bound to the Parts collection:

My grid definition is:

@(Html.Kendo().Grid(Model.Parts)
                    .Name("Parts")
                    .Columns(columns =>
                    {
                        columns.Bound(p => p.Quantity);
                        columns.Bound(p => p.Part.Id).EditorTemplateName("PartComboBox").ClientTemplate("#= Part ? Part.Name : '' #");
                        columns.Bound(p => p.Instructions);
                        columns.Command(command => command.Destroy()).Width(100);
                    }
    )
    .Navigatable()
     .Editable(edit => edit
         .Mode(GridEditMode.InCell)
         .CreateAt(GridInsertRowPosition.Bottom)
     )
     .DataSource(datasource => datasource
         .Ajax()
         .Model(model =>
         {
             model.Id(p => p.Id);
             model.Field(p => p.Part).DefaultValue(new Models.PartViewModel());
         })
            )
 
 
 
)

The PartComboBox editor template is this:

@(Html.Kendo().ComboBox()
        .Name("Part")
        .DataValueField("Id")
        .DataTextField("Name")
        .Filter(FilterType.Contains)
        .DataSource(source =>
        {
            source.Read(read =>
            {
                read.Action("GetParts", "RefData").Data(@<text>
        function()
        {
            var val=$("#Part").data("kendoComboBox").input.val();
        return {
            Name: val}
        }
                </text>);
            })
            .ServerFiltering(true);
        }
        )
)

I tried modifying this to apply the data_bind attribute to the ComboBox but that didn't change anything. I don't understand how to adapt the foreign key demo to my setup.
0
Daniel
Telerik team
answered on 16 Mar 2016, 12:08 PM
Hello,

I am not sure if i understand correctly the issue but if you wish to submit the grid data with a form as part of the assembly then you can use the approach demonstrated in this code-library project.

Regards,
Daniel
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
0
Bill Wingate
Top achievements
Rank 1
answered on 21 Mar 2016, 03:57 PM

I'm not trying to submit the grid as part of the form.

My problem is that if I bind using the ComboBox like this:

columns.Bound(p => p.Part.Id).EditorTemplateName("PartComboBox");

The cell (when not in edit mode) shows the part ID rather than the part name. I can fix that by changing to:

columns.Bound(p => p.Part.Id).EditorTemplateName("PartComboBox").ClientTemplate("#= Part ? Part.Name : '' #");

That works until I enter a new custom value in the ComboBox. The ComboBox shows the value, but once I leave Edit mode for the cell, the grid shows "undefined" for the value.

I tried various approaches of binding to "p.Part" instead of "p.Part.Id" but that doesn't work either. I either end up with the cell showing nothing or showing "[object Object]".

0
Daniel
Telerik team
answered on 23 Mar 2016, 11:30 AM
Hi,

It seems the approach with explicitly specifying the binding will not work for the combobox. Because of the name generated for the text input the correctly bound object will be overridden. In that case I can suggest to use a separate editor for the grid or to remove the text input name via code or to use a foreignkey column. I attached a sample project that demonstrates the suggested solutions.

Regards,
Daniel
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
0
Bill Wingate
Top achievements
Rank 1
answered on 28 Mar 2016, 09:00 PM

The demo solution you posted is showing problems similar to what I have been describing.

In the top grid ("Parts"), select a cell and enter a value that's not from the list, like "Part 109". When you leave the cell, it shows "undefined."

In the bottom grid ("PartsForeignKey"), if you enter a non-existent value the cell is empty when you leave it.

0
Daniel
Telerik team
answered on 31 Mar 2016, 08:33 AM
Hi,

The foreignkey column cannot be used for custom values because it can only show values available in the data that is passed initially on the server. The problem with displaying the value when binding to object can be avoided by changing the logic in the template but the binding will not work correctly after setting a custom value because the field will no longed be an object. Custom binding might be the best option for this scenario. I attached the project modified to demonstrate one possible implementation.

Regards,
Daniel
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
0
Bill Wingate
Top achievements
Rank 1
answered on 05 Apr 2016, 09:42 PM

Thank you--that seems to be working.

The last piece is that I need to do server filtering for the combo box data source, based on the entered text. I previously had this working, but since I adapted to use your code it's not. What is the id of the combo box now?

I have this for the data source:

source.Read(read =>
{
    read.Action("GetParts", "Home").Data(@<text>
function()
{
var val=$("#Part").data("kendoComboBox").input.val();
return {
userId: @ViewBag.UserId,
Name: val}
}

But using "#Part" doesn't work. How do I get the current value of the combobox?
0
Daniel
Telerik team
answered on 07 Apr 2016, 09:10 AM
Hi,

The id that will be generated by default would be "Part_Id". You can also use the HtmlAttributes method to set any ID to the input:
.HtmlAttributes(new { data_bind = "customValueObject:Part", data_skip="true", id = "Part"})


Regards,
Daniel
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
0
Bill Wingate
Top achievements
Rank 1
answered on 07 Apr 2016, 01:42 PM

I hadn't noticed that the sample you sent had the ID set to a Guid using the HtmlAttributes. Now I see.

Thanks for the help; I think I have this all working now.

Tags
ComboBox
Asked by
Bill Wingate
Top achievements
Rank 1
Answers by
Daniel
Telerik team
Bill Wingate
Top achievements
Rank 1
Share this question
or