Kendo DropDownList SelectedIndex not set on server side

1 Answer 1238 Views
DropDownList
Keith
Top achievements
Rank 1
Keith asked on 01 Oct 2021, 03:14 PM

On the post back from a razor page I am expecting the SelectedIndex to set a value for me. but it is always 0.

How do I get it to set the selectedindex? 

@(Html.Kendo().DropDownListFor(m => m.Contractor)        
        .SelectedIndex(Model.Contractor.CompanyId)
        .DataTextField("Text")
        .DataValueField("Id")
        .OptionLabel("Please select")
        .BindTo(ViewBag.CompanyId)
        )

Also tried:

@(Html.Kendo().DropDownListFor(m => m.Contractor)        
        .SelectedIndex(Model.LocationIdSelected)
        .DataTextField("Text")
        .DataValueField("Id")
        .OptionLabel("Please select")
        .BindTo(ViewBag.CompanyId)
        )
Keith
Top achievements
Rank 1
commented on 06 Oct 2021, 11:54 AM

I am not trying to set a default value. Which is what your example does. I need to know what value the user selected. Per my example if the user selects  the 5th option "Name 5" then the value returned to the server should not be 0. How do you tell on the server side what option was selected by the user. 
Aleksandar
Telerik team
commented on 11 Oct 2021, 09:00 AM

Thank you for the additional details. I have updated the initial answer based on the clarifications you shared, but I am still able to observe the value set via  the SelectedIndex configuration being sent back to the page handler method, responsible for handling the form submission.

1 Answer, 1 is accepted

Sort by
0
Accepted
Aleksandar
Telerik team
answered on 06 Oct 2021, 06:19 AM | edited on 11 Oct 2021, 08:59 AM

Hi Keith,

Below is the updated answer based on the additional data provided.

Page:

        

public void OnGet() { if (Contractor == null) { Contractor = new Contractor() { CompanyId = 3, ContractorId = 123, Name = "John Doe" }; var data = Enumerable.Range(1, 5).Select(x => new { Text = "Company " + x, Id = x }); ViewData["companies"] = data; } }

public IActionResult OnPost()
        {
            var selectedContractor = Request.Form["Contractor"];

            return RedirectToPage("Success");
        }

View:

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
    var token = Xsrf.GetAndStoreTokens(HttpContext).RequestToken;
}

@using TelerikAspNetCoreApp366.Data
@using Kendo.Mvc.UI

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf

<form action="/" method="post">
    @(Html.Kendo().DropDownListFor(m => m.Contractor)
        .SelectedIndex(Model.Contractor.CompanyId)
        .DataTextField("Text")
        .DataValueField("Id")
        .OptionLabel("Please select")
        .BindTo((System.Collections.IEnumerable)ViewData["companies"])
    )
    <button type="submit" class="k-button k-primary">Submit</button>
</form>
<script>
    $("form").append($("<input type='hidden' name='__RequestVerificationToken' value='@token' data-stop='true' />"))
</script>

Model:

    public class Contractor
    {
        public int ContractorId { get; set; }
        public string Name { get; set; }
        public int CompanyId { get; set; }
    }

As you can see in this updated screencast the selected index is set and sent back to the page handler responsible for the post action. Am I missing something crucial from the scenario you have?

The DropDownList HTML Helper renders an input element with id and name attributes set to the mode property to which it is bound - in this case Contractor:

<input id="Contractor" name="Contractor" type="text" value="" data-role="dropdownlist" style="display: none;">

The submitted value for this input is defined via the DataValueField and as you can see in the screencast the SelectedIndex is set and the value is summited back. 

I am also attaching the sample project for you to review.

Regards,
Aleksandar
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Keith
Top achievements
Rank 1
commented on 12 Oct 2021, 02:34 PM

I get a blank page when I run your code example. Sorry don't have time to debug it.

 

I have an open ticket on this issue: 1537806

Keith
Top achievements
Rank 1
commented on 12 Oct 2021, 05:36 PM

Attached is an example from the ticket. 

And my comments. for the code changes please see the ticket. Thanks. 

Using the DataValueField looks like it only works if your .Name value, in this case "ShipCity" is unique. I attached an update where I cloned the OrderViewModel. As you can see the one Dropdown will update both the ShipCity in the order and order2 objects. Since I will have several dropdown list referring to different models each having an Id field this is not the best solution. Is there a way to tie it to a model? 

Keep in mind that I will be using a Kendo wizard control, and the Dropdownlistfor control is not available in the wizard.  

Also I am not using .DataSource, I am using ViewBag but that not an issue here. 

Thanks.

Aleksandar
Telerik team
commented on 15 Oct 2021, 07:09 AM

I see that the context of the support case is the usage of the DropDownList as an Editor in a Wizard in RarorPages and that the provided suggestion has helped. I will post below the response from the case for the benefit of the community:

For a  Wizard component with two steps:
Step 1: It has an integrated Form that binds to the Model "OrderViewModel". The Form contains two DropDownLists that are bound to the Model properties "Contractor" and "User".

//Models

    public class OrderViewModel
    {
        public Company Contractor { get; set; }
        public User User { get; set; }
    }

    public class Company
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public class User
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

//Page

.Items(items =>
                    {
                        items.Add()
                               .Field(f => f.Contractor.Id)
                               .Label(label => label.Text("Company:"))
                               .Editor(e =>
                               {
                                   e.DropDownList()
                                   .SelectedIndex(Model.order.Contractor.Id)
                                   .DataTextField("Text")
                                   .DataValueField("Id")
                                   ...
                               });

                        items.Add()
                           .Field(f => f.User.Id)
                           .Label(label => label.Text("User:"))
                           .Editor(e =>
                           {
                               e.DropDownList()
                               .SelectedIndex(Model.order.User.Id)
                               .DataTextField("Text")
                               .DataValueField("Id")
                               ...
                           });
                    })

Step 2: It contains an integrated Form that binds to the Model "Company". The editor is a DropDownList that is bound to the Model property "Id".

.Items(items =>
                    {
                        items.Add()
                               .Field(f => f.Id)
                               .Label(label => label.Text("Company:"))
                               .Editor(e =>
                               {
                                   e.DropDownList()
                                   .SelectedIndex(Model.company.Id)
                                   .DataTextField("Text")
                                   .DataValueField("Id")
                                   ...
                               });
                    })

Once the forms are submitted, the fields are sent to the server as per the screenshot below:

 

Keith
Top achievements
Rank 1
commented on 15 Oct 2021, 11:45 AM

Basically, you can not use the SelectIndex property to tell what the user selected.  See below ticket for a answer and code sample supplied by Telerik for solution.  Thanks.

 

Ticket ID: 1537806

Aleksandar
Telerik team
commented on 20 Oct 2021, 09:11 AM

The SelectedIndex(System.Int32) configuration option, identical to the index configuration in jQuery. As documented in the APIs it is used to set the initially selected item in the DropDownList. The DropDownList helper will render an input element with id and name attributes. The value selected by the user will be sent as the value for that input element.
Tags
DropDownList
Asked by
Keith
Top achievements
Rank 1
Answers by
Aleksandar
Telerik team
Share this question
or