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

Problem with pre-select values on PostBack

2 Answers 164 Views
MultiSelect
This is a migrated thread and some comments may be shown as answers.
Sebastien Veilleux
Top achievements
Rank 1
Sebastien Veilleux asked on 03 Mar 2016, 06:10 PM

We are using the multiselect control with values pre-selection and ToDataSourceResult instance as describe in documentation.

Unfortunately, when we post our model and its ModelState is invalid, we return to the view and the control fails to display the pre-selection and the search also stop working.

Here is some sample snippet.

Model

public class CreateModel
{
    [Required]
    public string Name { get; set; }
 
    public List<int> ProductIds { get; set; }
    public List<Product> InitialProducts { get; set; }
}
 
public class Product
{
    public int ProductId { get; set; }
    public string ProductName { get; set; }
}

Controller

public class HomeController : Controller
{
    [HttpGet]
    public ActionResult Create()
    {
        var initialProduct = GetProductList().First();
 
        var model = new CreateModel
        {
            InitialProducts = new List<Product>(new[] { initialProduct }),
            ProductIds = new List<int>(new[] { initialProduct.ProductId })
        };
 
        return View(model);
    }
 
    [HttpPost]
    public ActionResult Create(CreateModel model)
    {
        if (ModelState.IsValid)
            return RedirectToAction("Success");
 
        model.InitialProducts = GetProductList().Where(p => model.ProductIds.Contains(p.ProductId)).ToList();
 
        return View(model);
    }
 
    [HttpGet]
    public ActionResult Success()
    {
        return View();
    }
 
    private static IEnumerable<Product> GetProductList()
    {
        return new[]
        {
            new Product { ProductId = 1, ProductName = "Chai" },
            new Product { ProductId = 2, ProductName = "Chang" },
            new Product { ProductId = 3, ProductName = "Book" },
            new Product { ProductId = 4, ProductName = "Fork" },
            new Product { ProductId = 5, ProductName = "Knife" },
            new Product { ProductId = 6, ProductName = "Spoon" },
            new Product { ProductId = 7, ProductName = "Dish" },
            new Product { ProductId = 8, ProductName = "Glass" },
            new Product { ProductId = 9, ProductName = "Cup" }
        };
    }
     
    [HttpPost]
    public JsonResult GetDataSourceProducts([DataSourceRequest] DataSourceRequest request)
    {
        var products = GetProductList();
 
        if (request.Filters != null && request.Filters.Count > 0)
        {
            var filter = (FilterDescriptor)request.Filters[0];
            products = products.Where(p => p.ProductName.ToLower().Contains((string)filter.Value)).AsEnumerable();
        }
 
        return Json(products.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
    }
}

View

@using (Html.BeginForm("Create", "Home"))
{
    <div>
        @Html.Kendo().TextBoxFor(m => m.Name)
        @Html.ValidationMessageFor(m => m.Name)
    </div>
 
    <div>
        @(Html.Kendo().MultiSelectFor(m => m.ProductIds)
              .DataTextField("ProductName")
              .DataValueField("ProductId")
              .Placeholder("Select products...")
              .AutoBind(false)
              .DataSource(source => source
                  .Custom()
                  .ServerFiltering(true)
                  .Type("aspnetmvc-ajax")
                  .Transport(transport => transport.Read(read => read.Action("GetDataSourceProducts", "Home")))
                  .Schema(schema => schema.Data("Data").Total("Total"))
              )
              .Filter(FilterType.Contains)
              .Value(Model.InitialProducts)
              )
    </div>
 
    <div>
        <button id="Save" type="submit">Save</button>
    </div>
}

 

Is there any kind of work around for this?

2 Answers, 1 is accepted

Sort by
0
Georgi Krustev
Telerik team
answered on 07 Mar 2016, 12:59 PM
Hello Sebastien Veilleux,

When same view is returned, the MVC wrapper will retrieve the values from the ModelState, because it needs to display the erroneous form state. In this case, the Value of the widget will not be equal to the Model.InitialProducts, but equal to the posted ProductIds. 

This is an expected behavior, and the only workaround is to remove the values from the ModelState (as it is shown in the aforementioned forum thread).

Regards,
Georgi Krustev
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
Sebastien Veilleux
Top achievements
Rank 1
answered on 07 Mar 2016, 03:59 PM

Thanks it is good to know.

I use ModelState.Remove("ProductIds") and it works now as I expected.

Tags
MultiSelect
Asked by
Sebastien Veilleux
Top achievements
Rank 1
Answers by
Georgi Krustev
Telerik team
Sebastien Veilleux
Top achievements
Rank 1
Share this question
or